首页 > 其他分享 >Rust 每日一库 —— Darling

Rust 每日一库 —— Darling

时间:2024-05-20 21:54:11浏览次数:19  
标签:derive struct pub 一库 input deref Darling AutoDeref Rust

Darling

1. 名词解释

field (字段)是指属于一个对象或数据结构的一个数据成员,在宏编程时我们往往期望获得字段的名词、字段的类型、以及额外的自定义属性

2. 使用原因

期望在过程宏中解析syn::DeriveInput得出申明性属性。
例1: 结构体中的 field ---> bar 中的 skip 属性为 true

#[derive(Lorem)]
pub struct Foo {
    #[lorem(skip)]
    bar: bool,
    baz: i64,
}

例2: 结构体本身具有一个属性 field 为 inner

#[allow(unused)]
#[derive(Debug, AutoDeref)]
#[deref(field = "inner")]
pub struct RespBulkString {
    inner: String,
    nothing: (),
}

3. 使用 Darling 的一般姿势,以 极客时间Rust auto_deref 为例

为结构体 RespBulkString 自动实现

#[allow(unused)]
#[derive(Debug, AutoDeref)]
#[deref(field = "inner")]
pub struct RespBulkString {
    inner: String,
    nothing: (),
}

为结构体 RespBulkString 自动实现

impl std::ops::Deref for RespBulkString {
    type Target = String;
    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}
impl std::ops::DerefMut for RespBulkString {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.inner
    }
}

3.1 在 lib.rs 中对外暴露 AutoDeref

#[proc_macro_derive(AutoDeref, attributes(deref))]
pub fn derive_auto_deref(input: TokenStream) -> TokenStream {
    let input = syn::parse_macro_input!(input as DeriveInput);
    println!("{:#?}", input);

    process_auto_deref(input).into()
}

3.2 编写转换函数 process_auto_deref

// 参数为 DeriveInput
pub(crate) fn process_auto_deref(input: DeriveInput) -> TokenStream {
}

3.3 定义 AutoDeref 的结构体

描述文本
// 使用 FromDeriveInput 宏自动实现 FromDeriveInput
//  AutoDeref 拥有函数  fn from_derive_input(input: &DeriveInput) -> Result<Self, Error>,用于解析 syn::DeriveInput
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(deref))]
struct AutoDeref {
    ident: syn::Ident,
    generics: syn::Generics,
    // Data 为 enum,前者代表使用 AutoRef 宏的是 enum 类型 —— 与事实不符
    //                       后者代表使用 AutoRef 宏的是 struct 类型
    data: Data<(), AutoDerefField>,
    #[darling(default)]
    field: Option<syn::Ident>,
    #[darling(default)]
    mutable: bool,
}

3.4 定义 AutoDerefField,AutoDeref 中的 data 对应多个 AutoDerefField

描述文本
#[derive(Debug, FromField)]
struct AutoDerefField {
    ident: Option<syn::Ident>,
    ty: syn::Type,
}

4. 拓展

#[derive(Lorem)]
pub struct Foo {
    #[lorem(skip)]
    bar: bool,
    baz: i64,
}

当中的 attributes 同样适用于struct 中的 field 官方示例

#[derive(Debug, FromField)]
#[darling(attributes(lorem))]
pub struct LoremField {
    ident: Option<Ident>,
    ty: Type,
    #[darling(default)]
    skip: bool,
}

#[derive(Debug, FromDeriveInput)]
#[darling(attributes(lorem), supports(struct_named))]
pub struct Lorem {
    ident: Ident,
    data: ast::Data<util::Ignored, LoremField>,
}

标签:derive,struct,pub,一库,input,deref,Darling,AutoDeref,Rust
From: https://www.cnblogs.com/wyzwsy/p/18202863

相关文章

  • 【rust】《Rust整合OpenCV ( Ubuntu.22.04系统 ) 》
    前言Ubuntu22.04的环境搭建、rust安装配置、VSCode安装等参照另一篇博文:https://www.cnblogs.com/-CO-/p/18197715环境搭建对应项##虚拟机版本VMware17##系统版本Ubuntu22.04.4##Rust版本Rust1.78.0##Rust依赖Opencv版本Opencv-rust0.7......
  • 【Linux】《VMware17搭建Ubuntu.22.04-Rust开发环境》
    下载VMware17安装包下载链接:创建虚拟机之后都默认就可以了。进入系统设置登录账号和密码以及修改下语言,剩余都默认即可。设置中文界面设置中文输入法接下来开始设置输入法切换快捷键设置使用Ctrl+Alt+T打开终端,输入ibus-setup重启,看一下是......
  • rust项目中通过log4rs将日志写入文件
    java项目中使用最广泛的日志系统应该是log4j(2)了。如果你也是一个Java程序员,可能在写rust的时候会想怎么能顺手地平移日志编写习惯到rust中来。log4rs就是干这个的。从名字就能看出来。将Java编程习惯代人rust不是一种好的方向,毕竟两种语言定位不同。不过单纯练手就无所谓了......
  • Rust winit 0.30.0版本简介
    不久前,Rust著名的跨平台窗体管理库winit发布了它的0.30.0版本,较之前的0.2x.x版本,新增了19个的模块API,改动大约19个模块API,移除了大约8个模块API。可见本次升级改动之大,主要是对事件循环、窗口管理的重构。鉴于目前网上较多的文章都是基于0.2x版本的winit的代码,存在时效性问题,所以......
  • Rust数据驱动-参数化测试
    需求假如有以下测试用例,同样的逻辑,我们需要测试多组数据。modtests{#[test]fntest_add(){leta=1;letb=2;assert_eq!(a+b,3);}}一般情况下我们不在用例中使用for循环(即subtests子测试模式)来验证多组数据。modtest......
  • OSS_PIPE:Rust编写的大规模文件迁移工具| 京东云技术团队
    文盘rust好久没有更新了。这段时间笔者用rust写了个小东西,跟各位分享一下背景随着业务的发展,文件数量和文件大小会急剧增加,文件迁移的数量和难度不断攀升。oss_pipe是rust编写的文件迁移工具,旨在支撑大规模的文件迁移场景。编写oss_pipe的初衷•同类产品面临的问题•rust......
  • 2024年,Rust和Go学习哪个更有优势
    在编程语言的世界里,技术的更新迭代速度一直都是非常快的。而在2024年这个特殊的年份,Rust和Go这两门编程语言备受关注,成为了许多程序员学习的焦点。那么,在这两者之间,到底该选择学习哪个,才能更具优势呢?本文将从各个方面分析比较Rust和Go,帮助读者更好地做出决策。1.语言特性比较Ru......
  • RustDesk 自建服务器部署和使用教程
    RustDesk是一个强大的开源远程桌面软件,是中国开发者的作品,它使用Rust编程语言构建,提供安全、高效、跨平台的远程访问体验。可以说是目前全球最火的开源远程桌面软件了,GitHub星星数量达到了惊人的64k!与TeamViewer、ToDesk等专有远程访问解决方案相比,RustDesk作为一个开源......
  • Rust工作空间(workspace)实践
    本文将介绍如何使用cargoworkspace来管理多个package,并通过实践介绍workspace的一些基础场景下的使用、配置方式。在rust中编写某些中小型项目时,我们通常不会将一个工程拆分为多个package,而是通过一个package下不同的目录模块来实现模块拆分,尽管大部分场景下这种开发方式已经足......
  • Rust 错误处理
    rust处理错误,不使用trycatch,而是使用Result<T,E>。简单的处理rust错误在各种关于rust错误处理的文档中,为了解释清楚其背后的机制,看着内容很多,不好理解。比如我们写一个方法,读取文件内容:fnread_file_to_string(file_path:String)->Result<String,io::Error>{le......