#debugging #derive-debug #injecting #rewriting #chain-calling #debug-ext

chain-debug

在不重写链式调用代码的情况下注入调试信息

2 个版本

0.1.1 2023年2月28日
0.1.0 2023年2月28日

#9 in #rewriting

MIT 许可证

4KB

chain-debug

使用方法

use chain_debug::DebugExt;

struct A {
    inner: B,
}

#[derive(Debug)]
struct B {
    s: String,
}

impl A {
    fn inner(&self) -> &B {
        &self.inner
    }
}

let a = A { ... };

a
  .inner()
  .debug()
  .s
  .debug()

为什么需要?

有时我会写一些像这样的代码:

let client = reqwest::Client::new();
let res = client
    .post("example...")
    .json(&payload)
    .send()
    .await
    .unwrap()
    .json::<Response>()
    .await
    .unwrap();

查询过程中可能会出现一些错误,最终 JSON 解析器将得到一个意外的 JSON 响应,我需要找出实际的内容。但是,不得不重写代码并打断链式调用来进行调试是不方便的。

let response = client.post(...).response();
println!("{response:?}")

如果我们可以...

// ...
    .send()
    .debug()
    .json()
    .debug()

解决方案

我们可以继承并扩展 std::fmt::Debug 特性

pub trait DebugExt {
    fn debug(&self) -> &Self
    where
        Self: Debug,
    {
        println!("{self:?}");
        self
    }
}

impl<D: Debug> DebugExt for D {}

然后任何具有 Debug 特性的结构体都可以自动具有 DebugExt 特性,因此我们可以将 .debug() 放入链中并检查值,而不必打断现有的代码。

沙盒链接: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d283e02ea1b1041e04b21fc478f10271

致谢

感谢 @SpriteOvO 教导我关于特性继承的部分。

无运行时依赖