Macro const_format::writec

source ·
macro_rules! writec {
    ( $writer:expr, $format_string:expr $( $(, $expr:expr )+ )? $(,)? ) => { ... };
}
Available on crate feature fmt only.
Expand description

Writes some formatted standard library and/or user-defined types into a buffer.

This macro evaluates to a Result<(), const_format::Error> which must be handled.

Syntax

The syntax is similar to that of other formatting macros in this crate:

ẁritec!(
    writer_expression,
    "formatting literal",
    positional_arg_0_expression,
    positional_arg_1_expression,
    named_arg_foo = expression,
    named_arg_bar = expression,
)

The syntax is otherwise the same as described in the const_format::fmt module.

Writers

The first argument must be a type that implements the WriteMarker trait, and has these inherent methods:

const fn borrow_mutably(&mut self) -> &mut Self
const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_>

This example below shows how to use this macro with a custom type.

Limitations

Integer arguments must have a type inferrable from context, more details in the Integer arguments section.

Examples

Ẁriting a Display impl.

#![feature(const_mut_refs)]

use const_format::{Error, Formatter, StrWriter};
use const_format::{impl_fmt, try_, writec};

pub struct Foo(u32, &'static str);

impl_fmt!{
    impl Foo;
    pub const fn const_display_fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
        try_!(writec!(f, "{},", self.0));
        try_!(writec!(f, "{:?};", self.1));
        Ok(())
    }
}

// Coerces the `&mut StrWriter<[u8; 128]>` to `&mut StrWriter<[u8]>`.
// This is necessary because the `as_str` method is defined for `StrWriter<[u8]>`.
let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);
writec!(writer, "{}", Foo(100, "bar"))?;

assert_eq!(writer.as_str(), r#"100,"bar";"#);

Writing to a custom type

This example demonstrates how you can use the ẁritec macro with a custom type, in this case it’s a buffer that is cleared every time it’s written.

#![feature(const_mut_refs)]

use const_format::marker_traits::{IsNotAStrWriter, WriteMarker};
use const_format::{Formatter, FormattingFlags};
use const_format::writec;

const ARRAY_CAP: usize = 20;
struct Array {
    len: usize,
    arr: [u8; ARRAY_CAP],
}

impl WriteMarker for Array{
    type Kind = IsNotAStrWriter;
    type This = Self;
}

impl Array {
    // Gets the part of the array that has been written to.
    pub const fn as_bytes(&self) -> &[u8] {
        const_format::utils::slice_up_to_len_alt(&self.arr, self.len)
    }

    pub const fn borrow_mutably(&mut self) -> &mut Self {
        self
    }

    pub const fn make_formatter(&mut self, flags: FormattingFlags) -> Formatter<'_> {
        Formatter::from_custom_cleared(&mut self.arr, &mut self.len, flags)
    }
}


let mut buffer = Array{ arr: [0; ARRAY_CAP], len: 0 };

writec!(buffer, "{:?}", [3u8, 5, 8, 13, 21])?;
assert_eq!(buffer.as_bytes(), b"[3, 5, 8, 13, 21]");

writec!(buffer, "{}{}", "Hello, world!", 100u16)?;
assert_eq!(buffer.as_bytes(), b"Hello, world!100");

Custom formatting.

This example demonstrates how you can access the Formatter in arguments to do custom formatting.

Note that return inside arguments returns from the function around the writec.

For more details on this you can look in the fmt module.

#![feature(const_mut_refs)]

use const_format::for_examples::Point3;
use const_format::{StrWriter, call_debug_fmt, try_, writec};

const P: Point3 = Point3{x: 5, y: 13, z: 21};

let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);

writec!(
    writer,
    "The options are: {}, and {}",
    |fmt| call_debug_fmt!(Option, Some(P), fmt),
    |fmt| call_debug_fmt!(Option, None::<Point3>, fmt),
)?;

assert_eq!(writer.as_str(), "The options are: Some(Point3 { x: 5, y: 13, z: 21 }), and None");

Locals in the format string

This example demonstrates how you can format local variables, by using their identifiers in the format string.

#![feature(const_mut_refs)]

use const_format::{Formatter, FormattingFlags, StrWriter, try_, writec};

const fn writeit(mut fmt: Formatter<'_>, foo: u32, bar: &str) -> const_format::Result {
    try_!(writec!(fmt, "{foo},{foo:?},{foo:#x},{foo:#b};"));
    try_!(writec!(fmt, "{bar},{bar:?}"));
    Ok(())
}

let writer: &mut StrWriter = &mut StrWriter::new([0; 128]);

writeit(writer.make_formatter(FormattingFlags::NEW), 100, "hello")?;

assert_eq!(writer.as_str(), r#"100,100,0x64,0b1100100;hello,"hello""#);