fish_printf/lib.rs
1/** Rust printf implementation, based on musl. */
2mod arg;
3pub use arg::{Arg, ToArg};
4
5mod fmt_fp;
6mod printf_impl;
7pub use printf_impl::{sprintf_locale, Error, FormatString};
8pub mod locale;
9pub use locale::{Locale, C_LOCALE, EN_US_LOCALE};
10
11#[cfg(test)]
12mod tests;
13
14/// A macro to format a string using `fish_printf` with C-locale formatting rules.
15///
16/// # Examples
17///
18/// ```
19/// use fish_printf::sprintf;
20///
21/// // Create a `String` from a format string.
22/// let s = sprintf!("%0.5g", 123456.0);
23/// assert_eq!(s, "1.2346e+05");
24///
25/// // Append to an existing string.
26/// let mut s = String::new();
27/// sprintf!(=> &mut s, "%0.5g", 123456.0);
28/// assert_eq!(s, "1.2346e+05");
29/// ```
30#[macro_export]
31macro_rules! sprintf {
32 // Write to a newly allocated String, and return it.
33 // This panics if the format string or arguments are invalid.
34 (
35 $fmt:expr, // Format string, which should implement FormatString.
36 $($arg:expr),* // arguments
37 $(,)? // optional trailing comma
38 ) => {
39 {
40 let mut target = String::new();
41 $crate::sprintf!(=> &mut target, $fmt, $($arg),*);
42 target
43 }
44 };
45
46 // Variant which writes to a target.
47 // The target should implement std::fmt::Write.
48 (
49 => $target:expr, // target string
50 $fmt:expr, // format string
51 $($arg:expr),* // arguments
52 $(,)? // optional trailing comma
53 ) => {
54 {
55 // May be no args!
56 #[allow(unused_imports)]
57 use $crate::ToArg;
58 $crate::printf_c_locale(
59 $target,
60 $fmt,
61 &mut [$($arg.to_arg()),*],
62 ).unwrap()
63 }
64 };
65}
66
67/// Formats a string using the provided format specifiers and arguments, using the C locale,
68/// and writes the output to the given `Write` implementation.
69///
70/// # Parameters
71/// - `f`: The receiver of formatted output.
72/// - `fmt`: The format string being parsed.
73/// - `args`: Iterator over the arguments to format.
74///
75/// # Returns
76/// A `Result` which is `Ok` containing the number of characters written on success, or an `Error`.
77///
78/// # Example
79///
80/// ```
81/// use fish_printf::{printf_c_locale, ToArg, FormatString};
82/// use std::fmt::Write;
83///
84/// let mut output = String::new();
85/// let fmt: &str = "%0.5g"; // Example format string
86/// let mut args = [123456.0.to_arg()];
87///
88/// let result = printf_c_locale(&mut output, fmt, &mut args);
89///
90/// assert!(result == Ok(10));
91/// assert_eq!(output, "1.2346e+05");
92/// ```
93pub fn printf_c_locale(
94 f: &mut impl std::fmt::Write,
95 fmt: impl FormatString,
96 args: &mut [Arg],
97) -> Result<usize, Error> {
98 sprintf_locale(f, fmt, &locale::C_LOCALE, args)
99}