You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现基于数据生成Trait的Rust宏以简化API客户端开发

用Rust宏自动生成API客户端Trait与实现

我们可以通过Rust的macro_rules!实现代码生成宏,自动创建Trait定义和Client类型的实现,消除重复样板代码。

宏定义

macro_rules! gen_code {
    ($trait_name:ident, $($method_name:ident = $return_ty:ty),* $(,)?) => {
        trait $trait_name {
            $(
                fn $method_name(&self) -> $return_ty;
            )*
        }

        impl $trait_name for Client {
            $(
                fn $method_name(&self) -> $return_ty {
                    self.client.get(stringify!($method_name)).into()
                }
            )*
        }
    };
}

使用示例

先定义依赖的基础类型(根据业务逻辑调整):

// 业务数据结构
struct Trades;
struct Quote;

// 内部客户端实现
struct InnerClient;
impl InnerClient {
    fn get(&self, endpoint: &str) -> impl Into<Vec<Trades>> + Into<Quote> {
        // 这里写实际的API请求逻辑
        unimplemented!()
    }
}

// 对外暴露的API客户端
struct Client {
    client: InnerClient,
}

然后调用宏生成代码:

gen_code! {
   APITrait,
   updated_trades = Vec<Trades>,
   new_quote = Quote,
}

生成的代码

宏展开后会生成如下代码(修正了你示例中返回类型的笔误):

trait APITrait {
    fn updated_trades(&self) -> Vec<Trades>;
    fn new_quote(&self) -> Quote;
}

impl APITrait for Client {
    fn updated_trades(&self) -> Vec<Trades> {
        self.client.get("updated_trades").into()
    }

    fn new_quote(&self) -> Quote {
        self.client.get("new_quote").into()
    }
}

核心细节说明

  • $trait_name:ident:捕获指定的Trait名称,支持自定义Trait标识
  • $($method_name:ident = $return_ty:ty),*:批量捕获方法名与返回类型,支持任意数量的方法定义
  • stringify!($method_name):将方法名转为字符串,直接作为API请求的端点路径
  • $(,)?:允许最后一个方法后带逗号,提升语法书写的灵活性
  • .into():要求InnerClient::get的返回类型实现了对应业务类型的From/Into trait,确保类型自动转换

内容的提问来源于stack exchange,提问作者Rol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:33:25