macro_rules! tokenize_core_fmt_to_writer {
($writer:expr, $($format_string:literal)PW_FMT_CONCAT+ $(, $args:expr)* $(,)?) => { ... };
}Expand description
Tokenize a core::fmt format string and arguments to a MessageWriter.
The format string is converted in to a printf and added token to the token
database.
tokenize_core_fmt_to_writer! and the accompanying MessageWriter trait
provide an optimized API for use cases like logging where the output of the
tokenization will be written to a shared/ambient resource like stdio, a
UART, or a shared buffer.
The writer_type should implement MessageWriter and Default traits.
The writer is instantiated with the Default allowing any intermediate
buffers to be declared on the stack of the internal writing engine instead
of the caller’s stack.
See token for an explanation on how strings are tokenized and entries
are added to the token database. The token’s domain is set to "".
Returns a pw_status::Result<()>.
tokenize_core_fmt_to_writer! supports concatenation of format strings as
described in pw_format::macros::FormatAndArgs.
§Errors
pw_status::Error::OutOfRange-MessageWriterdoes not have enough space to fit tokenized data.- others -
tokenize_core_fmt_to_writer!will pass on any errors returned by theMessageWriter.
§Code Size
This data was collected by examining the disassembly of a test program built for a Cortex M0.
| Tokenized Message | Per Call-site Cost (bytes) |
|---|---|
| no arguments | 10 |
one i32 argument | 18 |
§Example
use pw_status::Result;
use pw_stream::{Cursor, Write};
use pw_tokenizer::{MessageWriter, tokenize_core_fmt_to_writer};
const BUFFER_LEN: usize = 32;
// Declare a simple MessageWriter that uses a [`pw_status::Cursor`] to
// maintain an internal buffer.
struct TestMessageWriter {
cursor: Cursor<[u8; BUFFER_LEN]>,
}
impl Default for TestMessageWriter {
fn default() -> Self {
Self {
cursor: Cursor::new([0u8; BUFFER_LEN]),
}
}
}
impl MessageWriter for TestMessageWriter {
fn write(&mut self, data: &[u8]) -> Result<()> {
self.cursor.write_all(data)
}
fn remaining(&self) -> usize {
self.cursor.remaining()
}
fn finalize(self) -> Result<()> {
let len = self.cursor.position();
// 4 bytes used to encode the token and one to encode the value 42.
assert_eq!(len, 5);
Ok(())
}
}
// Tokenize a format string and argument into the writer. Note how we
// pass in the message writer's type, not an instance of it.
let len = tokenize_core_fmt_to_writer!(TestMessageWriter, "The answer is {}", 42 as i32)?;