#display #derive-debug #debugging #enums #derive #macro #delegates

构建 delegate-display

为只有一个成员的结构体/枚举使用 derive(Display, Debug)

11个稳定版本

2.1.1 2023年9月28日
2.1.0 2023年9月26日
1.0.8 2023年4月3日
1.0.7 2023年3月4日
1.0.1 2023年2月28日

#413构建工具 中排名

Download history 1990/week @ 2024-04-04 2123/week @ 2024-04-11 2397/week @ 2024-04-18 2175/week @ 2024-04-25 2433/week @ 2024-05-02 2267/week @ 2024-05-09 2248/week @ 2024-05-16 2475/week @ 2024-05-23 2215/week @ 2024-05-30 2176/week @ 2024-06-06 2942/week @ 2024-06-13 2368/week @ 2024-06-20 2604/week @ 2024-06-27 2832/week @ 2024-07-04 2933/week @ 2024-07-11 2451/week @ 2024-07-18

11,339 每月下载量
用于 19 个crate(2个直接使用)

MIT 许可证

27KB
350

允许您在具有 Display & Debug 特性的结构体上派生 0..=1 字段 & 枚举,其中每个变体都具有 0..=1 字段 - 以下是输入/输出示例。

master CI badge crates.io badge docs.rs badge dependencies badge

示例

Newtype结构体
// Input
#[derive(delegate_display::DelegateDisplay)]
struct Foo(SomeType);

// Output
impl fmt::Display for Foo {
  #[inline]
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    fmt::Display::fmt(&self.0, f)
  }
}
只有一个字段的结构体
// Input
#[derive(delegate_display::DelegateDebug)]
struct Foo { some_field: SomeType }

// Output
impl fmt::Debug for Foo {
  #[inline]
  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
    fmt::Debug::fmt(&self.some_field, f)
  }
}
枚举
// Input
enum MyEnum {
  Foo,
  Bar(SomeType),
  Qux { baz: SomeType }
}

// Output
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  match self {
    Self::Foo => f.write_str("Foo"),
    Self::Bar(inner) => DebugOrDisplay::fmt(inner, f),
    Self::Qux { baz } => DebugOrDisplay::fmt(baz, f),
  }
}
空结构体 & 枚举
// Input
struct Foo;
struct Bar{}
struct Qux();
enum Baz {}

// Output
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
  Ok(())
}
自定义泛型边界

属性名称为 ddebug 用于 Debugddisplay 用于 Displaydboth 用于两者的通用配置。 ddebugddisplay 优先于 dboth

  • base_bounds 将正在派生的任何特质作为泛型边界添加到结构体/枚举的每个泛型参数
  • bounds(...) 允许您指定特定的边界
// Input
#[derive(DelegateDisplay, DelegateDebug)]
#[dboth(base_bounds)]
#[ddisplay(bounds(F: Display, B: Clone + Display))]
enum Foo<F, B> {
  Foo(F),
  Bar(B),
}

// Output
impl<F: Display, B: Clone + Display> Display for Foo<F, B> { /* ... */}
impl<F: Debug, B: Debug> Debug for Foo<F, B> { /* ... */ }
类型委托

可用于进一步美化输出。

/// Some type that `Deref`s to the type we want to use in our formatting, in this case, `str`.
#[derive(Debug)]
struct Wrapper(&'static str);

#[derive(DelegateDebug)]
#[ddebug(delegate_to(str))] // ignore `Wrapper` and debug the `str` it `Deref`s instead
struct Typed(Wrapper);

#[derive(DelegateDebug)] // Included for comparison
struct Base(Wrapper);

assert_eq!(format!("{:?}", Typed(Wrapper("foo"))), "\"foo\"");
assert_eq!(format!("{:?}", Base(Wrapper("bar"))), "Wrapper(\"bar\")");
无效输入
#[derive(DelegateDisplay, Debug)]
#[dboth(delegate_to(String))] // `delegate_to` is not supported on enums
enum SomeEnum {
  Foo(Arc<String>)
}
#[derive(delegate_display::DelegateDisplay)]
#[ddisplay(base_bounds, bounds(T: Display))] // `base_bounds` and `bounds` are mutually exclusive
struct Generic<T>(T);
#[derive(delegate_display::DelegateDisplay)]
#[ddisplay(base_bounds)]
#[ddisplay(base_bounds)] // `dbodh` and `ddisplay` can be mixed, but the same option can't be used twice
struct Foo<T>(T);
#[derive(delegate_display::DelegateDebug)]
struct TooManyFields1 {
  foo: u8,
  bar: u8, // Only one field permitted
}
#[derive(delegate_display::DelegateDebug)]
struct TooManyFields2(u8, u8); // too many fields
#[derive(delegate_display::DelegateDebug)]
enum SomeEnum {
  A, // this is ok
  B(u8), // this is ok
  C { foo: u8 }, // this is ok
  D(u8, u8), // Only one field permitted
  E { foo: u8, bar: u8 } // Only one field permitted
}
#[derive(delegate_display::DelegateDebug)]
union Foo { bar: u8 } // Unions are not supported

依赖

~0.3–0.8MB
~19K SLoC