Skip to content

Commit 8184759

Browse files
ede1998Dirbaio
authored andcommitted
make capacity inferrable
1 parent 5e1aff3 commit 8184759

File tree

1 file changed

+30
-11
lines changed

1 file changed

+30
-11
lines changed

src/string.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,10 @@ pub fn format<const N: usize>(args: Arguments<'_>) -> Result<String<N>, fmt::Err
601601

602602
/// Macro that creates a fixed capacity [`String`]. Equivalent to [`format!`](https://doc.rust-lang.org/std/macro.format.html).
603603
///
604-
/// The first argument is the capacity of the `String`. The following arguments work in the same way as the regular macro.
604+
/// The macro's arguments work in the same way as the regular macro.
605+
///
606+
/// It is possible to explicitly specify the capacity of the returned string as the first argument.
607+
/// In this case it is necessary to disambiguate by separating the capacity with a semicolon.
605608
///
606609
/// # Errors
607610
///
@@ -616,22 +619,31 @@ pub fn format<const N: usize>(args: Arguments<'_>) -> Result<String<N>, fmt::Err
616619
///
617620
/// ```
618621
/// # fn main() -> Result<(), core::fmt::Error> {
619-
/// use heapless::format;
622+
/// use heapless::{format, String};
620623
///
621-
/// format!(4, "test")?;
622-
/// format!(15, "hello {}", "world!")?;
623-
/// format!(20, "x = {}, y = {y}", 10, y = 30)?;
624+
/// // Notice semicolon instead of comma!
625+
/// format!(4; "test")?;
626+
/// format!(15; "hello {}", "world!")?;
627+
/// format!(20; "x = {}, y = {y}", 10, y = 30)?;
624628
/// let (x, y) = (1, 2);
625-
/// format!(12, "{x} + {y} = 3")?;
629+
/// format!(12; "{x} + {y} = 3")?;
630+
///
631+
/// let implicit: String<10> = format!("speed = {}", 7)?;
626632
/// # Ok(())
627633
/// # }
628634
/// ```
629635
#[macro_export]
630636
macro_rules! format {
631-
($max:literal, $($arg:tt)*) => {{
637+
// Without semicolon as separator to disambiguate between arms, Rust just
638+
// chooses the first so that the format string would land in $max.
639+
($max:expr; $($arg:tt)*) => {{
632640
let res = $crate::string::format::<$max>(core::format_args!($($arg)*));
633641
res
634-
}}
642+
}};
643+
($($arg:tt)*) => {{
644+
let res = $crate::string::format(core::format_args!($($arg)*));
645+
res
646+
}};
635647
}
636648

637649
macro_rules! impl_try_from_num {
@@ -900,20 +912,27 @@ mod tests {
900912
fn format() {
901913
let number = 5;
902914
let float = 3.12;
903-
let formatted = format!(15, "{:0>3} plus {float}", number).unwrap();
915+
let formatted = format!(15; "{:0>3} plus {float}", number).unwrap();
916+
assert_eq!(formatted, "005 plus 3.12")
917+
}
918+
#[test]
919+
fn format_inferred_capacity() {
920+
let number = 5;
921+
let float = 3.12;
922+
let formatted: String<15> = format!("{:0>3} plus {float}", number).unwrap();
904923
assert_eq!(formatted, "005 plus 3.12")
905924
}
906925

907926
#[test]
908927
fn format_overflow() {
909928
let i = 1234567;
910-
let formatted = format!(4, "13{}", i);
929+
let formatted = format!(4; "13{}", i);
911930
assert_eq!(formatted, Err(core::fmt::Error))
912931
}
913932

914933
#[test]
915934
fn format_plain_string_overflow() {
916-
let formatted = format!(2, "123");
935+
let formatted = format!(2; "123");
917936
assert_eq!(formatted, Err(core::fmt::Error))
918937
}
919938
}

0 commit comments

Comments
 (0)