Skip to content

Commit 13ae739

Browse files
committed
Add format_to! macro
It's a version of `format!` which allows appending to an existing `String`. Unlike `write!`, it doesn't require a trait import and unwrap. See https://internals.rust-lang.org/t/add-an-easier-way-to-append-t-display-to-string-to-stdlib/10607 for some preliminary discussion. See https://github.com/rust-analyzer/rust-analyzer/blob/3ffa915cbcf4d7a3988142cd94da0463acc87c8a/crates/stdx/src/macros.rs#L12-L19 for an equivalent macro used in rust-analyzer quite a bit.
1 parent a9cd294 commit 13ae739

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

library/alloc/src/macros.rs

+25
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,28 @@ macro_rules! format {
107107
res
108108
}}
109109
}
110+
111+
/// Like [`format!`], but appends to an existing string
112+
///
113+
///
114+
/// [`format!`]: crate::format
115+
///
116+
/// # Examples
117+
///
118+
/// ```
119+
/// #![feature(format_to)]
120+
///
121+
/// let mut buf = String::new();
122+
/// format_to!(buf, "hello");
123+
/// format_to!(buf, ", world!");
124+
/// assert_eq!(buf, "hello, world!");
125+
/// ```
126+
#[macro_export]
127+
#[unstable(feature = "format_to", issue = "none", reason = "new API")]
128+
#[allow_internal_unstable(liballoc_internals)]
129+
macro_rules! format_to {
130+
($buf:expr $(, $($arg:tt)*)? ) => {{
131+
// Redirect via method call syntax to get autoref behavior
132+
$buf.__push_fmt($crate::__export::format_args!($($($arg)*)?));
133+
}}
134+
}

library/alloc/src/string.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,12 @@ impl String {
15851585
let slice = self.vec.into_boxed_slice();
15861586
unsafe { from_boxed_utf8_unchecked(slice) }
15871587
}
1588+
1589+
#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
1590+
#[doc(hidden)]
1591+
pub fn __push_fmt(&mut self, args: fmt::Arguments<'_>) {
1592+
fmt::Write::write_fmt(self, args).unwrap();
1593+
}
15881594
}
15891595

15901596
impl FromUtf8Error {

library/std/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@
261261
#![feature(external_doc)]
262262
#![feature(fn_traits)]
263263
#![feature(format_args_nl)]
264+
#![feature(format_to)]
264265
#![feature(gen_future)]
265266
#![feature(generator_trait)]
266267
#![feature(global_asm)]
@@ -373,6 +374,8 @@ pub use alloc_crate::boxed;
373374
pub use alloc_crate::fmt;
374375
#[stable(feature = "rust1", since = "1.0.0")]
375376
pub use alloc_crate::format;
377+
#[unstable(feature = "format_to", issue = "none", reason = "new API")]
378+
pub use alloc_crate::format_to;
376379
#[stable(feature = "rust1", since = "1.0.0")]
377380
pub use alloc_crate::rc;
378381
#[stable(feature = "rust1", since = "1.0.0")]

0 commit comments

Comments
 (0)