Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add format_to! macro #76240

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions library/alloc/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,28 @@ macro_rules! format {
res
}}
}

/// Like [`format!`], but appends to an existing string
///
///
/// [`format!`]: crate::format
///
/// # Examples
///
/// ```
/// #![feature(format_to)]
///
/// let mut buf = String::new();
/// format_to!(buf, "hello");
/// format_to!(buf, ", world!");
/// assert_eq!(buf, "hello, world!");
/// ```
#[macro_export]
#[unstable(feature = "format_to", issue = "none", reason = "new API")]
#[allow_internal_unstable(liballoc_internals)]
macro_rules! format_to {
($buf:expr $(, $($arg:tt)*)? ) => {{
// Redirect via method call syntax to get autoref behavior
$buf.__push_fmt($crate::__export::format_args!($($($arg)*)?));
}}
}
6 changes: 6 additions & 0 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1585,6 +1585,12 @@ impl String {
let slice = self.vec.into_boxed_slice();
unsafe { from_boxed_utf8_unchecked(slice) }
}

#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")]
#[doc(hidden)]
pub fn __push_fmt(&mut self, args: fmt::Arguments<'_>) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't it just be an inherent write_fmt method, so write!(...) always works on String instead of introducing a semi-hidden method and a whole new macro?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That won’t be backward compatible: write_fmt already exists on String (via Write trait) and returns a result.

Copy link
Contributor

@CryZe CryZe Sep 2, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I guess it would have to have the same signature. So I guess the unwrapping would unfortunately stay in that case. Though maybe it could use Result<(), !> and somehow be compatible and not require unwrapping... (Not sure if the stars align for that one though🤔)

fmt::Write::write_fmt(self, args).unwrap();
}
}

impl FromUtf8Error {
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@
#![feature(external_doc)]
#![feature(fn_traits)]
#![feature(format_args_nl)]
#![feature(format_to)]
#![feature(gen_future)]
#![feature(generator_trait)]
#![feature(global_asm)]
Expand Down Expand Up @@ -373,6 +374,8 @@ pub use alloc_crate::boxed;
pub use alloc_crate::fmt;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::format;
#[unstable(feature = "format_to", issue = "none", reason = "new API")]
pub use alloc_crate::format_to;
#[stable(feature = "rust1", since = "1.0.0")]
pub use alloc_crate::rc;
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down