Skip to content

Commit

Permalink
add format_shared and format_queue macros
Browse files Browse the repository at this point in the history
  • Loading branch information
TimLuq committed Jan 7, 2025
1 parent 2ee6651 commit e0acf36
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,58 @@ macro_rules! concat_str_static {
}
};
}

#[cfg(feature = "alloc")]
#[doc(hidden)]
#[inline]
pub fn __format_shared<'a>(args: core::fmt::Arguments<'_>) -> crate::StringData<'a> {
if let Some(args2) = args.as_str() {
return crate::StringData::from_static(args2);
}
let mut me = crate::SharedStrBuilder::new();
core::fmt::Write::write_fmt(&mut me, args).unwrap();
me.build_str()
}

/// Formats a format string with arguments into a shared `StringData`.
#[cfg(feature = "alloc")]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
#[macro_export]
macro_rules! format_shared {
($fmt:expr) => {
$crate::__format_shared(core::format_args!($fmt))
};
($fmt:expr, $($args:tt)*) => {
$crate::__format_shared(core::format_args!($fmt, $($args)*))
};
}

#[cfg(feature = "queue")]
#[doc(hidden)]
#[inline]
#[allow(clippy::unwrap_used)]
pub fn __format_queue<'a>(args: core::fmt::Arguments<'_>) -> crate::StringQueue<'a> {
if let Some(args2) = args.as_str() {
return crate::StringQueue::with_item(crate::StringData::from_static(args2));
}
let mut me = crate::StringQueue::new();
core::fmt::Write::write_fmt(&mut me, args).unwrap();
me
}

/// Formats a format string with arguments into an owned `StringQueue`.
///
/// There is currently no way to optimize shallow clones of `StringData` or `StringQueue` instances, so prefer to use [`StringQueue::push_back`] or [`StringQueue::append`] to build a queue of prepared strings.
#[cfg(feature = "queue")]
#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
#[cfg_attr(docsrs, doc(cfg(feature = "queue")))]
#[macro_export]
macro_rules! format_queue {
($fmt:expr) => {
$crate::__format_queue(core::format_args!($fmt))
};
($fmt:expr, $($args:tt)*) => {
$crate::__format_queue(core::format_args!($fmt, $($args)*))
};
}
9 changes: 9 additions & 0 deletions src/queue/string_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,15 @@ impl core::fmt::Debug for crate::StringQueue<'_> {
}
}

impl core::fmt::Write for crate::StringQueue<'_> {
#[inline]
#[allow(clippy::min_ident_chars)]
fn write_str(&mut self, s: &str) -> core::fmt::Result {
self.push_back(StringData::from_borrowed(s).into_shared());
Ok(())
}
}

impl Default for crate::StringQueue<'_> {
#[inline]
fn default() -> Self {
Expand Down
26 changes: 26 additions & 0 deletions src/test/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,29 @@ fn test_macros_str() {
static HW: &str = crate::concat_str_static!("hello", " ", "world");
assert_eq!(HW, "hello world");
}

#[cfg(feature = "alloc")]
#[test]
fn test_macros_format_shared() {
static CHOICES: &[&str] = &[" you", " world", "... hello... hello", "oooooooo!"];
static CHOICE_ATOM: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
let choice = CHOICES
[CHOICE_ATOM.fetch_add(1, core::sync::atomic::Ordering::Relaxed) as usize % CHOICES.len()];
let hw = crate::format_shared!("{}{}", "hello", choice);
assert_eq!(hw.len(), 5 + choice.len());
assert!(hw.starts_with("hello"));
assert!(hw.ends_with(choice));
}

#[cfg(feature = "queue")]
#[test]
fn test_macros_format_queue() {
static CHOICES: &[&str] = &[" you", " world", "... hello... hello", "oooooooo!"];
static CHOICE_ATOM: core::sync::atomic::AtomicU32 = core::sync::atomic::AtomicU32::new(0);
let choice = CHOICES
[CHOICE_ATOM.fetch_add(1, core::sync::atomic::Ordering::Relaxed) as usize % CHOICES.len()];
let hw = crate::format_queue!("{}{}", "hello", choice);
assert_eq!(hw.len(), 5 + choice.len());
assert!(hw.starts_with("hello"));
assert!(hw.ends_with(choice));
}

0 comments on commit e0acf36

Please sign in to comment.