chain-debug

Crates.iochain-debug
lib.rschain-debug
version0.1.1
sourcesrc
created_at2023-02-28 06:13:21.426028
updated_at2023-02-28 06:17:11.850308
descriptionInjecting debug without rewriting chain-calling code
homepage
repositoryhttps://github.com/Avimitin/chain-debug
max_upload_size
id796649
size3,994
Jiongjia Lu (Avimitin)

documentation

README

chain-debug

Usage

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()

Why?

Sometime I will write some code like:

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

And there might be some error during the query, then the final json parser will get an unexpected JSON response that I need to figure out the actual content. But it is inconvenient to have to rewrite the code and break the chain call to debug.

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

What if we can...

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

Solution

We can inherit and extend the std::fmt::Debug trait:

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

impl<D: Debug> DebugExt for D {}

Then any struct that has the Debug trait implied can automatically have DebugExt trait implied, so we can put .debug() into the chain and inspect the value without breaking the existing code.

Playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=d283e02ea1b1041e04b21fc478f10271

Credit

Thanks to @SpriteOvO for teaching me about the trait inheritance part.

Commit count: 0

cargo fmt