tokenize_core_fmt_to_writer

Macro tokenize_core_fmt_to_writer 

Source
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

§Code Size

This data was collected by examining the disassembly of a test program built for a Cortex M0.

Tokenized MessagePer Call-site Cost (bytes)
no arguments10
one i32 argument18

§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)?;