#[report]Expand description
Annotate a new logging group with a custom message.
§Usage
Currently, the ability to use proc macro attributes on expressions
is only available when enabling the proc-macro-hygiene feature
using the nightly compiler. To circumvent this limitation, report
will parse the functions and expand all subsequent calls to the
similarly named attribute macro. In the following steps, any expression
annotated with a report will display all nested logging events under
the same group. If there are no events to be logged, the group header
will not be included in the final report.
use report::{report, info, log};
#[report]
#[log("Test report")]
fn main() {
#[report("First group")]
{
info!("This info is attached to the first group");
}
#[report("Second group")]
info!("This info is attached to the second group");
#[report("Omitted group")]
{
//This group will not be included, since there are no events
}
}╭────────────────────────────────────────────────────────────────────────────────────────────╮
│ Test report │
├─┬──────────────────────────────────────────────────────────────────────────────────────────┤
│ ├── First group │
│ │ ╰── info: This info is attached to the first group │
│ ╰── Second group │
│ ╰── info: This info is attached to the second group │
╰────────────────────────────────────────────────────────────────────────────────────────────╯§Borrowing of format arguments
Just like any other macro in this crate, the format string used by
the println! macro can be supplied as an argument. It is, however,
important to note that the actual string formatting happens after
the expression is evaluated. This means all arguments will be borrowed
for the scope of the expression and will make it impossible to use
elements that are moved and do not implement the Copy
trait. Mutable references can’t be used in the formatting string, either.
The reason for this is that a group may be excluded from the report,
making it a waste of resources to format the string in advance.
use report::{Result, report};
use std::fs::File;
#[report]
fn open_file() -> Result {
let path = String::from("Cargo.toml");
#[report("Opening file {path:?}")]
let _file = File::open(path)?; //cannot move out of 'path' because it is borrowed
Ok(())
}use report::{Result, report};
use std::fs::File;
#[report]
fn open_file() -> Result {
let path = String::from("Cargo.toml");
#[report("Opening file {path:?}")]
let _file = File::open(path.as_str())?; //this works because path is no longer moved
Ok(())
}