logfn === This crate provides the `logfn` attribute macro for inserting logging code into your function. This is heavily inspired by [elichai's `log-derive`](https://github.com/elichai/log-derive) crate. Currently we support 2 types of logging. - Pre logging - Post logging And we have a plan to add `Time logging` and `Count logging` type. Each `logfn` attribute injects a single logging code. You can put as many `logfn` as you want. ```rust # use logfn::logfn; # use std::num::ParseIntError; #[logfn(Pre, Debug, "{fn} will be executed")] #[logfn(Post, Debug, "{fn} is executed", if = "Result::is_ok")] #[logfn(Post, Error, "Error {fn}: {ret:?}", if = "Result::is_err")] fn atoi(a: &str) -> Result { usize::from_str_radix(a, 10) } ``` The detail is documented below. ## Pre logging The following attribute injects logging code **before** function is called. ```rust use logfn::logfn; #[logfn(Pre, Info, "executing {fn}...")] fn add(a: usize, b: usize) -> usize { a + b } ``` The resulting code will looks like ```rust fn add(a: usize, b: usize) -> usize { log::info!("executing add..."); { a + b } } ``` ## Post logging You also be able to inject logging code **after** function is called. ```rust use logfn::logfn; #[logfn(Post, Info, "executed {fn}!")] fn add(a: usize, b: usize) -> usize { a + b } ``` The resulting code will looks like ```rust fn add(a: usize, b: usize) -> usize { let res = (move || { a + b })(); log::info!("executed add!"); res } ``` ## Conditional logging You can configure the condition on which logging code is fired. To do that, please add `if` argument with a path to the function which takes reference to returned value and returns `true` when you want to fire the logging code. ## Note Conditional logging is only supported in post logging for now. ```rust use logfn::logfn; #[logfn(Post, Warn, "checked add is failed!!", if = "Option::is_none")] fn checked_add(a: usize, b: usize) -> Option { a.checked_add(b) } ``` ## Message formatting We support below format patterns. - "{fn}" interpolates function name - "{ret:?}" or "{ret}" interpolates returned value ```rust # use std::num::ParseIntError; use logfn::logfn; #[logfn(Post, Error, "Error while {fn}: {ret:?}", if = "Result::is_err")] fn atoi(s: &str) -> Result { usize::from_str_radix(s, 10) } ``` ## Async function Async function is also supported. ```rust use logfn::logfn; #[logfn(Post, Debug, "{fn} is executed")] async fn add_fut(a: usize, b: usize) -> usize { a + b } ```