alloc_safe/
fmt.rs

1//! Utilities for formatting and printing strings.
2
3use std::fmt::{self, Write};
4
5#[repr(transparent)]
6struct StrBuf(String);
7
8impl Write for StrBuf {
9    #[inline]
10    fn write_str(&mut self, s: &str) -> fmt::Result {
11        self.0.try_reserve(s.len()).map_err(|_| fmt::Error)?;
12        self.0.push_str(s);
13        Ok(())
14    }
15}
16
17/// The `try_format` function takes an `Arguments` struct and returns the resulting
18/// formatted string.
19#[inline]
20pub fn try_format(args: fmt::Arguments<'_>) -> Result<String, fmt::Error> {
21    let capacity = args.estimated_capacity();
22    let mut output = String::new();
23    output.try_reserve(capacity).map_err(|_| fmt::Error)?;
24
25    let mut buf = StrBuf(output);
26    buf.write_fmt(args)?;
27    Ok(buf.0)
28}
29
30/// Creates a `String` using interpolation of runtime expressions.
31///
32/// The first argument `try_format!` receives is a format string. This must be a string
33/// literal. The power of the formatting string is in the `{}`s contained.
34///
35/// Additional parameters passed to `try_format!` replace the `{}`s within the
36/// formatting string in the order given unless named or positional parameters
37/// are used; see [`std::fmt`] for more information.
38///
39/// A common use for `try_format!` is concatenation and interpolation of strings.
40#[macro_export]
41macro_rules! try_format {
42    ($($arg:tt)*) => {{
43        let res = $crate::try_format(format_args!($($arg)*));
44        res
45    }}
46}