Struct const_format::fmt::StrWriter

source ·
pub struct StrWriter<A: ?Sized = [u8]> { /* private fields */ }
Available on crate feature fmt only.
Expand description

A wrapper over an array usable to build up a &str at compile-time.

Calling methods

Certain StrWriter methods require a StrWriter<[u8]> to be called, and since constructing StrWriter from an array produces a StrWriter<[u8; N]>, it must be cast to call them.

StrWriter’s type parameter defaults to [u8], so every instance of a StrWriter as a type is a StrWriter<[u8]>.

Example of casting it:

let writer: &mut StrWriter<[u8; 8]> = &mut StrWriter::new([0; 8]);

// Casts `&StrWriter<[u8; 8]>` to `&StrWriter`
writer.unsize();

// Casts `&StrWriter<[u8; 8]>` to `&StrWriter`
writer.r();

// Coerces the `&mut StrWriter<[u8; 8]>` to `&mut StrWriter`
let _writer: &mut StrWriter = writer;

// Casts `&mut StrWriter<[u8; 8]>` to `StrWriterMut<'_>`,
// which defines methods for mutating `StrWriter`
let _writer = writer.as_mut();

StrWriterMut

StrWriter can be borrowed into a StrWriterMut, which provides methods for writing a formatted string.

Example:

use const_format::StrWriter;

let mut buffer: &mut StrWriter = &mut StrWriter::new([0; 100]);

let mut writer = buffer.as_mut();
writer.write_str("Your password is: ");
writer.write_str_debug("PASSWORD");

assert_eq!(writer.as_str(), r#"Your password is: "PASSWORD""#);

Examples

Formatting into associated constant

This example shows how you can construct a formatted &'static str from associated constants.

#![feature(const_mut_refs)]

use const_format::{StrWriter, writec, unwrap};

trait Num {
    const V: u32;
}

struct Two;

impl Num for Two {
    const V: u32 = 2;
}

struct Three;

impl Num for Three {
    const V: u32 = 3;
}

struct Mul<L, R>(L, R);

const fn compute_str(l: u32, r: u32) -> StrWriter<[u8; 128]> {
    let mut writer = StrWriter::new([0; 128]);
    unwrap!(writec!(writer, "{} * {} == {}", l, r, l * r ));
    writer
}

impl<L: Num, R: Num> Mul<L, R> {
    const __STR: &'static StrWriter<[u8]> = &compute_str(L::V, R::V);
    const STR: &'static str = Self::__STR.as_str_alt();
}

assert_eq!(Mul::<Two,Three>::STR, "2 * 3 == 6");
assert_eq!(Mul::<Three,Three>::STR, "3 * 3 == 9");

Implementations§

source§

impl<A> StrWriter<A>

source

pub const fn new(array: A) -> Self

Constructs a StrWriter from a u8 array

source§

impl<A: ?Sized> StrWriter<A>

source

pub const fn buffer(&self) -> &A

Accesses the underlying buffer immutably.

Example
use const_format::StrWriter;

let buffer: &mut StrWriter = &mut StrWriter::new([0; 7]);
assert_eq!(buffer.buffer(), &[0; 7]);

buffer.as_mut().write_str("foo")?;
assert_eq!(buffer.buffer(), b"foo\0\0\0\0");

buffer.as_mut().write_str("bar")?;
assert_eq!(buffer.buffer(), b"foobar\0");
source

pub const fn len(&self) -> usize

How long the string this wrote is.

Example
use const_format::StrWriter;

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
assert_eq!(buffer.len(), 0);

buffer.as_mut().write_str("foo")?;
assert_eq!(buffer.len(), 3);

buffer.as_mut().write_str("bar")?;
assert_eq!(buffer.len(), 6);
source

pub const fn is_empty(&self) -> bool

Checks whether the string this wrote is empty.

Example
use const_format::StrWriter;

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
assert!( buffer.is_empty() );

buffer.as_mut().write_str("foo")?;
assert!( !buffer.is_empty() );
source§

impl StrWriter

source

pub const fn capacity(&self) -> usize

Gets the maximum length for a string written into this.

Trying to write more that the capacity causes an error, returning back an Err(Error::NotEnoughSpace)

Example
use const_format::{Error, StrWriter};

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
assert_eq!(buffer.capacity(), 64);

buffer.as_mut().write_ascii_repeated(b'A', 64)?;
assert_eq!(buffer.capacity(), 64);

assert_eq!(buffer.as_mut().write_str("-").unwrap_err(), Error::NotEnoughSpace);
assert_eq!(buffer.capacity(), 64);
source

pub const fn remaining_capacity(&self) -> usize

Checks how many more bytes can be written.

Example
use const_format::{Error, StrWriter};

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);
assert_eq!(buffer.remaining_capacity(), 64);

buffer.as_mut().write_str("foo")?;
assert_eq!(buffer.remaining_capacity(), 61);

buffer.as_mut().write_ascii_repeated(b'a', 61)?;
assert_eq!(buffer.remaining_capacity(), 0);

assert_eq!(buffer.as_mut().write_str(" ").unwrap_err(), Error::NotEnoughSpace);
source

pub const fn truncate(&mut self, length: usize) -> Result<(), Error>

Truncates this StrWriter to length.

If length is greater than the current length, this does nothing.

Errors

Returns an Error::NotOnCharBoundary if length is not on a char boundary.

Example
use const_format::{Error, StrWriter};

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);

buffer.as_mut().write_str("foo bâr baz");
assert_eq!(buffer.as_str(), "foo bâr baz");

assert_eq!(buffer.truncate(6).unwrap_err(), Error::NotOnCharBoundary);

buffer.truncate(3)?;
assert_eq!(buffer.as_str(), "foo");

buffer.as_mut().write_str("ooooooo");
assert_eq!(buffer.as_str(), "fooooooooo");
source

pub const fn clear(&mut self)

Truncates this StrWriter to length 0.

Example
use const_format::{Error, StrWriter};

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);

buffer.as_mut().write_str("foo")?;
assert_eq!(buffer.as_str(), "foo");

buffer.clear();
assert_eq!(buffer.as_str(), "");
assert!(buffer.is_empty());

buffer.as_mut().write_str("bar");
assert_eq!(buffer.as_str(), "bar");
source

pub const fn as_bytes_alt(&self) -> &[u8]

Gets the written part of this StrWriter as a &[u8]

The slice is guaranteed to be valid utf8, so this is mostly for convenience.

Runtime

If the “rust_1_64” feature is disabled, this takes time proportional to self.capacity() - self.len().

If the “rust_1_64” feature is enabled, it takes constant time to run.

Example
#![feature(const_mut_refs)]

use const_format::{StrWriter, StrWriterMut};

const fn slice() -> StrWriter<[u8; 64]> {
    let mut buffer = StrWriter::new([0; 64]);
    let mut writer = StrWriterMut::new(&mut buffer);
    writer.write_str("Hello, World!");
    buffer
}

const SLICE: &[u8] = {
    const PROM: &'static StrWriter = &slice();
    PROM.as_bytes_alt()
};


assert_eq!(SLICE, "Hello, World!".as_bytes());
source

pub const fn as_str_alt(&self) -> &str

Gets the written part of this StrWriter as a &str

Runtime

If the “rust_1_64” feature is disabled, this takes time proportional to self.capacity() - self.len().

If the “rust_1_64” feature is enabled, it takes constant time to run.

Example
#![feature(const_mut_refs)]

use const_format::StrWriter;
use const_format::{unwrap, writec};


const CAP: usize = 128;

const __STR: &StrWriter = &{
    let mut writer =  StrWriter::new([0; CAP]);

    // Writing the array with debug formatting, and the integers with hexadecimal formatting.
    unwrap!(writec!(writer, "{:X}", [3u32, 5, 8, 13, 21, 34]));

    writer
};

const STR: &str = __STR.as_str_alt();

fn main() {
    assert_eq!(STR, "[3, 5, 8, D, 15, 22]");
}
source

pub const fn as_str(&self) -> &str

Gets the written part of this StrWriter as a &str

Constness

This can be called in const contexts by enabling the “rust_1_64” feature.

Alternative

You can also use the as_str_alt method, which is always available, but takes linear time to run when the “rust_1_64” feature is disabled.

source

pub const fn as_bytes(&self) -> &[u8]

Gets the written part of this StrWriter as a &[u8]

The slice is guaranteed to be valid utf8, so this is mostly for convenience.

Constness

This can be called in const contexts by enabling the “rust_1_64” feature.

Example
use const_format::StrWriter;

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);

buffer.as_mut().write_str("Hello, World!");

assert_eq!(buffer.as_bytes(), "Hello, World!".as_bytes());
source

pub const fn as_mut(&mut self) -> StrWriterMut<'_>

Borrows this StrWriter<[u8]> into a StrWriterMut, most useful for calling the write_* methods.

use const_format::StrWriter;

let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);

buffer.as_mut().write_str_range("trust", 1..usize::MAX);

assert_eq!(buffer.as_str(), "rust");
source

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

Constructs a Formatter that writes into this StrWriter, which can be passed to debug and display formatting methods.

Example
#![feature(const_mut_refs)]

use const_format::{Error, Formatter, FormattingFlags, StrWriter, call_debug_fmt};

use std::ops::Range;

const fn range_debug_fmt(
    slice: &[Range<usize>],
    f: &mut Formatter<'_>
) -> Result<(), Error> {
    // We need this macro to debug format arrays of non-primitive types
    // Also, it implicitly returns a `const_format::Error` on error.
    call_debug_fmt!(array, slice, f);
    Ok(())
}

fn main() -> Result<(), Error> {
    let buffer: &mut StrWriter = &mut StrWriter::new([0; 64]);

    range_debug_fmt(
        &[0..14, 14..31, 31..48],
        &mut buffer.make_formatter(FormattingFlags::new().set_binary())
    )?;
    
    assert_eq!(buffer.as_str(), "[0..1110, 1110..11111, 11111..110000]");

    Ok(())
}
source§

impl<const N: usize> StrWriter<[u8; N]>

source

pub const fn r(&self) -> &StrWriter<[u8]>

Casts a &StrWriter<[u8; N]> to a &StrWriter<[u8]>, for calling methods defined on StrWriter<[u8]> (most of them).

Example
use const_format::StrWriter;

let mut buffer = StrWriter::new([0; 64]);

buffer.as_mut().write_str("Hello,");
buffer.as_mut().write_str(" world!");

assert_eq!(buffer.r().as_str(), "Hello, world!");
source

pub const fn unsize(&self) -> &StrWriter<[u8]>

Casts a &StrWriter<[u8; N]> to a &StrWriter<[u8]>, for calling methods defined on StrWriter<[u8]> (most of them).

Example
use const_format::StrWriter;

let mut buffer = StrWriter::new([0; 64]);

buffer.as_mut().write_str("Hello,");
buffer.as_mut().write_str(" world!");

assert_eq!(buffer.unsize().as_str(), "Hello, world!");
source

pub const fn as_mut(&mut self) -> StrWriterMut<'_>

Borrows this StrWriter<[u8; N]> into a StrWriterMut.

Example
use const_format::StrWriter;

let mut buffer = StrWriter::new([0; 64]);

buffer.as_mut().write_str_range("trust", 1..usize::MAX);

assert_eq!(buffer.r().as_str(), "rust");
source§

impl<A: ?Sized> StrWriter<A>

source

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

For borrowing this mutably in macros, without getting nested mutable references.

Trait Implementations§

source§

impl<A: Clone + ?Sized> Clone for StrWriter<A>

source§

fn clone(&self) -> StrWriter<A>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<A: Debug + ?Sized> Debug for StrWriter<A>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: ?Sized> WriteMarker for StrWriter<T>

§

type Kind = IsAStrWriter

Whether this is a StrWriter or not, this can be either of IsAStrWriter or IsNotAStrWriter
§

type This = StrWriter<T>

The type after dereferencing, implemented as type This = Self; for all non-reference types
source§

impl<A: Copy + ?Sized> Copy for StrWriter<A>

Auto Trait Implementations§

§

impl<A: ?Sized> RefUnwindSafe for StrWriter<A>where A: RefUnwindSafe,

§

impl<A: ?Sized> Send for StrWriter<A>where A: Send,

§

impl<A: ?Sized> Sync for StrWriter<A>where A: Sync,

§

impl<A: ?Sized> Unpin for StrWriter<A>where A: Unpin,

§

impl<A: ?Sized> UnwindSafe for StrWriter<A>where A: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.