#format-string #debugging #formatting #macro-derive #derive #proc-macro

debugify

std::fmt::Debug 设计的派生宏,专注于减少样板代码。支持格式化字符串和格式化函数。

2 个不稳定版本

0.2.0 2023年12月14日
0.1.0 2023年12月14日

#194 in 值格式化

MIT/Apache

24KB
362 代码行


debugify

std::fmt::Debug 设计的派生宏,专注于减少样板代码。支持格式化字符串和格式化函数。

格式化

格式化可以指定为格式化字符串或格式化函数的路径。格式化函数必须遵循以下签名:fn(&T) -> String

属性

在属性冲突的情况下,优先级顺序为

  1. 字段属性
  2. 字段名称
  3. 字段类型

如果没有指定格式,则使用默认格式。

项目属性

这些属性应用于结构体或枚举。

field_name

应用于项目内部具有给定名称的所有字段的格式化。

use debugify::Debugify;

#[derive(Debugify)]
#[debugify(field_name(
    [bar, biz] = "foobar{}",
    baz = "foobaz{}",
))]
struct Foo {
    bar: i32,
    baz: String,
    biz: &'static str,
    qux: i64,

}

let foo = Foo {
    bar: 123,
    baz: "hello".to_string(),
    biz: "world",
    qux: 456,
};

let foo_debug = format!("{foo:?}");
assert_eq!(foo_debug, "Foo { bar: foobar123, baz: foobazhello, biz: foobarworld, qux: 456 }");

field_type

应用于项目内部具有给定类型的所有字段的格式化。

use debugify::Debugify;

#[derive(Debugify)]
#[debugify(field_type(
    [i32, &'static str] = "foobar{}",
    String = "foobaz{}",
))]
struct Foo {
    bar: i32,
    baz: String,
    biz: &'static str,
    qux: i64,
}

let foo = Foo {
    bar: 123,
    baz: "hello".to_string(),
    biz: "world",
    qux: 456,
};

let foo_debug = format!("{foo:?}");
assert_eq!(foo_debug, "Foo { bar: foobar123, baz: foobazhello, biz: foobarworld, qux: 456 }");

字段属性

当前仅支持格式指定符字段属性。

use debugify::Debugify;

#[derive(Debugify)]
#[debugify(field_name(bar = "foo{}"))]
struct Foo {
    #[debugify("bar{}")]
    bar: i32,
    baz: String,
}

let foo = Foo {
    bar: 123,
    baz: "hello".to_string(),
};

let foo_debug = format!("{foo:?}");
assert_eq!(foo_debug, "Foo { bar: bar123, baz: \"hello\" }");

字段属性优先于项目属性。

枚举

也支持枚举。项目属性应用于所有变体,每个变体基本上被视为结构体。

use debugify::Debugify;

#[derive(Debugify)]
#[debugify(field_name([biz, qux] = "foo{}"))]
enum Foo {
    Bar {
        biz: i32,
        qux: String,
    },
    Baz {
        biz: i32,
        #[debugify("qux{}")]
        qux: String,
        quant: i64,
    }
}

let foo_1 = Foo::Bar {
    biz: 123,
    qux: "hello".to_string(),
};
let foo_2 = Foo::Baz {
    biz: 456,
    qux: "world".to_string(),
    quant: 789,
};

let foo_1_debug = format!("{foo_1:?}");
assert_eq!(foo_1_debug, "Bar { biz: foo123, qux: foohello }");

let foo_2_debug = format!("{foo_2:?}");
assert_eq!(foo_2_debug, "Baz { biz: foo456, qux: quxworld, quant: 789 }");

元组和单元结构体和变体

元组结构体和变体也支持字段格式属性。当然,这些与字段名称规则完全不冲突。

单元结构体和变体按正常方式格式化。

use debugify::Debugify;

#[derive(Debugify)]
#[debugify(field_type(String = "foo{}"))]
struct Foo(
    #[debugify("number{}")]
    i32,
    String,
    i32
);

let foo = Foo(64, "bar".into(), 128);
let foo_debug = format!("{foo:?}");
assert_eq!(foo_debug, "Foo(number64, foobar, 128)")

依赖关系

~0.4–1MB
~23K SLoC