#convert #struct #macro

just-convert

结构体简单转换

6个版本

0.1.6 2023年12月6日
0.1.5 2023年12月5日
0.1.3 2023年11月29日

#246 in 过程宏

MIT许可协议

30KB
696

just-convert

结构体简单转换

github crates.io docs.rs

示例

#[derive(JustConvert, Default)]
#[convert(from_into(other::Mouse))]
#[convert(from_into(Cat, default))]
struct Dog {
    #[convert(unwrap(from(Cat)))]
    name: String,
    #[convert(skip(from(other::Mouse)))]
    #[convert(map(from(Cat, ". as i64"), into(Cat, ". as u64")))]
    age: i64,

    // inner of Option must be autoconvert
    #[convert(skip(from_into(other::Mouse)))]
    #[convert(map = ".map(Into::into)")]
    error: Option<DogError>,
}

#[derive(JustConvert, Default)]
struct Cat {
    name: Option<String>,
    age: u64,
    // inner of Option must be autoconvert
    error: Option<CatError>,
}

mod other {
    pub struct Mouse {
        pub name: String,
    }
}

同时转换两侧

指定from_into的值作为#[convert(from_intoStruct))],而不是单独指定frominto

#[derive(JustConvert)]
#[convert(from_into(some::B))]
struct A {
    // ...
}

重命名字段

#[derive(JustConvert)]
#[convert(from_into(some::B))]
struct A {
    #[convert(rename = user_id)]
    id: String,
}

struct B {
    user_id: String,
}

执行转换的任意表达式

使用map属性指定任意表达式

要访问当前字段,使用点字符,例如,".get_value()"。要访问当前结构体,使用this构造,例如,"this.field.get_value()"

#[derive(JustConvert)]
#[convert(from(B))]
struct A {
    // call any method of this field
    #[convert(map = ".to_hex_string()")]
    id: Uuid,
    // casting (or "this.age as i64")
    #[convert(map = ". as i64")]
    age: i64,
    // call any expression
    #[convert(map = "format!(\"id: {}, age: {}\", this.id, this.age)")]
    message: String,
}

struct B {
    id: String,
    age: u64,
}

自动转换Option或Vec内部类型(以及Option和Vec

#[derive(JustConvert)]
#[convert(from(B))]
struct A {
    value: Option<ValueA>,
    items: Vec<ValueA>,
}

struct B {
    value: Option<ValueB>,
    items: Vec<ValueB>,
}

忽略某些字段

使用skip属性忽略转换

#[derive(JustConvert)]
#[convert(from(B))]
struct A {
    id: String,
    #[convert(skip)]
    age: i64,
}

struct B {
    id: String
}

声明多个转换

根据需要多次使用#[convert(...)]属性

#[derive(JustConvert)]
#[convert(from(B))]
#[convert(from_into(C))]
struct A {
    id: String,
    #[convert(skip)]
    age: i64,
}

struct B {
    id: String,
}

struct C {
    id: String,
}

为每个转换指定属性的值

可选地,您可以指定属性值适用于哪种转换。例如,只为from转换重命名字段#[convert(rename(from = new_name))]或为特定转换#[convert(rename(from(StructName, new_name)))]

值可以专业化的规则

  • 布尔值 #[convert(wrap)]#[convert(wrap(from))]#[convert(wrap(from(StructName)))]
  • 其他(带赋值)#[convert(map = "some_expr")]#[convert(map(from = "some_expr"))]#[convert(map(from(StructName, "some_expr")))]
#[derive(JustConvert)]
#[convert(from(B))]
#[convert(from_into(C))]
struct A {
    #[convert(rename(from_into(C, c_id)))]
    #[convert(rename(from = user_id))] // or #[convert(rename(from(B, user_id)))]
    id: String,
    #[convert(skip)]
    age: i64,
}

struct B {
    user_id: String,
}

struct C {
    c_id: String,
}

灵感来源

感谢 struct-convertderive-from-ext

依赖关系

~270–720KB
~17K SLoC