Macro cli_toolbox::debug[][src]

macro_rules! debug {
    ($result : expr => OK $ok : ident $debug : block) => { ... };
    ($result : expr => OK $debug : block) => { ... };
    ($result : expr => OK $ok : ident $succeeded : block ERR $err : ident $failed
 : block) => { ... };
    ($result : expr => OK $ok : ident $succeeded : block ERR $failed : block) => { ... };
    ($result : expr => OK $succeeded : block ERR $err : ident $failed : block) => { ... };
    ($result : expr => OK $succeeded : block ERR $failed : block) => { ... };
    ($result : expr => OK $succeeded : expr, $($ok_val : expr), * ; ERR $failed :
 expr, $($err_val : expr), * ;) => { ... };
    ($result : expr => OK $succeeded : expr, $($ok_val : expr), * ; ERR $failed :
 expr ;) => { ... };
    ($result : expr => OK $succeeded : expr, $($ok_val : expr), * ; _ERR $failed :
 expr, $($err_val : expr), * ;) => { ... };
    ($result : expr => OK $succeeded : expr, $($ok_val : expr), * ; _ERR $failed :
 expr ;) => { ... };
    ($result : expr => OK $succeeded : expr ; ERR $failed : expr,
 $($err_val : expr), * ;) => { ... };
    ($result : expr => OK $succeeded : expr ; ERR $failed : expr ;) => { ... };
    ($result : expr => OK $succeeded : expr ; _ERR $failed : expr,
 $($err_val : expr), * ;) => { ... };
    ($result : expr => OK $succeeded : expr ; _ERR $failed : expr ;) => { ... };
    ($result : expr => _OK $succeeded : expr, $($ok_val : expr), * ; ERR $failed :
 expr, $($err_val : expr), * ;) => { ... };
    ($result : expr => _OK $succeeded : expr, $($ok_val : expr), * ; ERR $failed :
 expr ;) => { ... };
    ($result : expr => _OK $succeeded : expr, $($ok_val : expr), * ; _ERR $failed
 : expr, $($err_val : expr), * ;) => { ... };
    ($result : expr => _OK $succeeded : expr, $($ok_val : expr), * ; _ERR $failed
 : expr ;) => { ... };
    ($result : expr => _OK $succeeded : expr ; ERR $failed : expr,
 $($err_val : expr), * ;) => { ... };
    ($result : expr => _OK $succeeded : expr ; ERR $failed : expr ;) => { ... };
    ($result : expr => _OK $succeeded : expr ; _ERR $failed : expr,
 $($err_val : expr), * ;) => { ... };
    ($result : expr => _OK $succeeded : expr ; _ERR $failed : expr ;) => { ... };
    ($result : expr => OK $debug : expr, $($val : expr), *) => { ... };
    ($result : expr => OK $debug : expr) => { ... };
    ($result : expr => _OK $debug : expr, $($val : expr), *) => { ... };
    ($result : expr => _OK $debug : expr) => { ... };
    ($result : expr => ERR $err : ident $debug : block) => { ... };
    ($result : expr => ERR $debug : block) => { ... };
    ($result : expr => ERR $debug : expr, $($val : expr), *) => { ... };
    ($result : expr => ERR $debug : expr) => { ... };
    ($result : expr => _ERR $debug : expr, $($val : expr), *) => { ... };
    ($result : expr => _ERR $debug : expr) => { ... };
    ($debug : block) => { ... };
    (ERR $debug : expr) => { ... };
    (ERR $debug : expr, $($val : expr), *) => { ... };
    ($debug : expr) => { ... };
    ($debug : expr, $($val : expr), *) => { ... };
    (@ OK $debug : expr) => { ... };
    (@ OK $debug : expr, $($val : expr), *) => { ... };
    (@ ERR $debug : expr) => { ... };
    (@ ERR $debug : expr, $($val : expr), *) => { ... };
}
Expand description

The debug! macro provides debug only code evaluation and user output.

Features

  • you can output basic or formatted debug information to stdout or stderr

  • you can execute a block of debug code

  • you can operate conditionally based on expressions that evaluate to Result<T,E>

    • conditionally output basic or formatted debug information to stdout or stderr

      Ok or Err result value automatically appended to output

      Ok or Err result value can be suppressed by prefixing the OK and/or ERR keywords with an underscore, i.e. _OK or _ERR

      outputs that append result values expect conditional expressions to evaluate to Result<T: Debug, E: Debug>

    • conditionally execute a block of debug code - optionally use result value in code block

  • prefixes output messages appropriately, i.e. “DEBUG: ...” or “ERROR: ...

Unconditional Output Examples

stdout

  • basic output to stdout
debug! { "debug output" }
DEBUG: debug output
  • formatted output to stdout
debug! { "debug output with formatted value {}", 42 }
DEBUG: debug output with formatted value 42

stderr

  • basic output to stderr
debug! { "descriptive error message" }
ERROR: descriptive error message
  • formatted output to stderr
debug! { "descriptive error message with formatted value {}", -42 }
ERROR: descriptive error message with formatted value -42

Conditional Output Examples

Using expressions that evaluate to Result<T,E> you can control debug output.

Expecting Ok<T>

  • outputs only if Result<T,E> is Ok<T>, appending the value to the end
debug! { foo() => OK "debug output when foo is OK" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Ok(42) }
DEBUG: debug output when foo is OK: 42
  • does not output if Result<T,E> is Err<E>
debug! { foo() => OK "debug output when foo is OK" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Err(false) }
  • the Ok<T> value can be suppressed by prefixing the OK keyword with an underscore, i.e. _OK
debug! { foo() => _OK "debug output when foo is OK" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Ok(42) }
DEBUG: debug output when foo is OK

Expecting ERR<E>

  • outputs only if Result<T,E> is ERR<E>, appending the exception to the end
debug! { foo() => ERR "error message when foo is ERR" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Err(false) }
ERROR: error message when foo is OK: false
  • does not output if Result<T,E> is OK<T>_
debug! { foo() => ERR "error message when foo is ERR" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Ok(42) }
  • the ERR<E> value can be suppressed by prefixing the ERR keyword with an underscore, i.e. _ERR
debug! { foo() => _ERR "error message when foo is ERR" }

#[cfg(debug_assertions)]
fn foo() -> Result<i32, bool> { Err(false) }
ERROR: error message when foo is ERR

Conditional Output Examples - Exhaustive

The previous set of conditional examples addressed the simple case of checking for a single outcome of a conditional expression.

You can also use conditional expressions exhaustively to handle both outcomes.

All of the features described also apply:

  • result values are appended automatically to end of output
  • result values can be suppressed
  • output messages can be formatted
debug! {
    foo() =>
        // with additional formatting and discards ok value
        _OK "debug output when foo is OK; {}", 42;
        // no additional formatting and appends err value
        ERR "error message when foo is ERR";
}

#[cfg(debug_assertions)]
fn foo() -> Result<bool, i32> { Ok(true) }
DEBUG: debug output when foo is OK; 42

Unconditional Code Block Example

  • execute a block of code only in debug
debug! {{
    let foo = foo();

    if foo != 42 {
        panic!("run for your lives, the sky is falling!")
    }

    fn foo() -> i32 { 42 }
}}

Conditional Code Block Examples

Using expressions that evaluate to Result<T,E> you can control debug code block execution.

Expecting Ok<T>

  • executes only if Result<T,E> is Ok<T>
debug! {
    junk() => OK {
        let foo = foo();

        if foo != 42 {
            panic!("run for your lives, the sky is falling!")
        }

        fn foo() -> i32 { 42 }
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Ok(42) }
  • does not execute if Result<T,E> is Err<E>
debug! {
    junk() => OK {
        panic!("run for your lives, the sky is falling!")
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Err(true) }
  • the Ok<T> value can be captured by providing a valid identifier
debug! {
    junk() => OK ok {
        let foo = foo();

        if ok != 42 || foo != 42 {
            panic!("run for your lives, the sky is falling!")
        }

        fn foo() -> i32 { 42 }
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Ok(42) }

Expecting ERR<E>

  • executes only if Result<T,E> is ERR<E>
debug! {
    junk() => ERR {
        let foo = foo();

        if foo != 42 {
            panic!("run for your lives, the sky is falling!")
        }

        fn foo() -> i32 { 42 }
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Err(true) }
  • does not execute if Result<T,E> is OK<T>
debug! {
    junk() => ERR {
        panic!("run for your lives, the sky is falling!")
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Ok(42) }
  • the ERR<E> value can be captured by providing a valid identifier
debug! {
    junk() => ERR err {
        let foo = foo();

        if !err || foo != 42 {
            panic!("run for your lives, the sky is falling!")
        }

        fn foo() -> i32 { 42 }
    }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Err(true) }

Conditional Code Blocks Examples - Exhaustive

Similar to conditional debug output, you can also use conditional expressions exhaustively to handle both outcomes for executing debug code blocks.

As before, all of the features described for conditional code blocks also apply:

  • result values are suppressed by default
  • result values can be capture to be used in the executing code block branch
debug! {
    junk() =>
        // captures ok value to use in code block
        OK ok {
            if ok != 42 {
                panic!("just a little, don't be so dramatic: the sky is not falling")
            }
        }
        // defaults to not capturing err value
        ERR { reset_some_arbitrary_state() }
}

#[cfg(debug_assertions)]
fn junk() -> Result<i32, bool> { Ok(42) }

fn reset_some_arbitrary_state() { /* ... */ }