diff --git a/crates/oxc_span/src/compact_str.rs b/crates/oxc_span/src/compact_str.rs index 8fdf482b6fc3b..3cd38cffecbf2 100644 --- a/crates/oxc_span/src/compact_str.rs +++ b/crates/oxc_span/src/compact_str.rs @@ -126,6 +126,12 @@ impl From for CompactStr { } } +impl From for CompactStr { + fn from(s: CompactString) -> Self { + Self(s) + } +} + impl<'s> From<&'s CompactStr> for Cow<'s, str> { fn from(value: &'s CompactStr) -> Self { Self::Borrowed(value.as_str()) @@ -251,10 +257,38 @@ impl schemars::JsonSchema for CompactStr { } } +/// Creates a `CompactStr` using interpolation of runtime expressions. +/// +/// The first argument `format_compact_str!` receives is a format string. +/// This must be a string literal. +/// The power of the formatting string is in the `{}`s contained. +/// +/// Additional parameters passed to `format_compact_str!` replace the `{}`s within +/// the formatting string in the order given unless named or +/// positional parameters are used; see [`std::fmt`] for more information. +/// +/// A common use for `format_compact_str!` is concatenation and interpolation +/// of strings. +/// The same convention is used with [`print!`] and [`write!`] macros, +/// depending on the intended destination of the string. +/// +/// # Panics +/// +/// `format_compact_str!` panics if a formatting trait implementation returns +/// an error. +#[macro_export] +macro_rules! format_compact_str { + ($($arg:tt)*) => { + $crate::CompactStr::from($crate::__internal::format_compact!($($arg)*)) + } +} + #[cfg(test)] mod test { use compact_str::CompactString; + use crate::format_compact_str; + use super::CompactStr; #[test] @@ -266,4 +300,9 @@ mod test { assert_eq!("foo", &foo); assert_eq!(foo.into_compact_string(), CompactString::new("foo")); } + + #[test] + fn test_format_compact_str() { + assert_eq!(format_compact_str!("foo{}bar", 123), "foo123bar"); + } } diff --git a/crates/oxc_span/src/lib.rs b/crates/oxc_span/src/lib.rs index 2e8745f7772b7..c311a2ed2e228 100644 --- a/crates/oxc_span/src/lib.rs +++ b/crates/oxc_span/src/lib.rs @@ -18,3 +18,9 @@ pub use crate::{ }, span::{GetSpan, GetSpanMut, Span, SPAN}, }; + +#[doc(hidden)] +pub mod __internal { + // Used by `format_compact_str!` macro defined in `compact_str.rs` + pub use ::compact_str::format_compact; +}