1#[macro_export]
36macro_rules! formatx {
37 ($template: expr $(,)?) => {
38 || -> ::std::result::Result<String, $crate::Error> {
39 $crate::Template::new($template)?.text()
40 }()
41 };
42
43 ($template: expr, $($values: tt)*) => {
44 || -> ::std::result::Result<String, $crate::Error> {
45 let mut template = $crate::Template::new($template)?;
46 $crate::_formatx_internal!(template, $($values)*);
47 template.text()
48 }()
49 };
50}
51
52#[macro_export]
53#[doc(hidden)]
54macro_rules! _formatx_internal {
55 ($template: expr, $name: ident = $value: expr $(,)?) => {
56 $template.replace(stringify!($name), $value);
57 };
58
59 ($template: expr, $value: expr $(,)?) => (
60 $template.replace_positional($value);
61 );
62
63 ($template: expr, $name: ident = $value: expr, $($values: tt)*) => {
64 $template.replace(stringify!($name), $value);
65 $crate::_formatx_internal!($template, $($values)*);
66 };
67
68 ($template: expr, $value:expr, $($values: tt)*) => {
69 $template.replace_positional($value);
70 $crate::_formatx_internal!($template, $($values)*);
71 };
72}
73
74#[cfg(test)]
75mod tests {
76 use crate::formatx;
77
78 macro_rules! formatx_test {
79 ($template: expr, $($values: tt)*) => {
80 assert_eq!(formatx!($template, $($values)*).unwrap(), format!($template, $($values)*))
81 }
82 }
83
84 #[test]
85 fn text() {
86 assert_eq!(formatx!("Hello").unwrap(), format!("Hello"));
87 }
88
89 #[test]
90 fn positional() {
91 formatx_test!("Hello, {}!", "world");
92 formatx_test!("The number is {}", 1);
93 formatx_test!("{} {}", 1, 2);
94 }
95
96 #[test]
97 fn named() {
98 formatx_test!("{value}", value = 4);
99 formatx_test!("{argument}", argument = "test");
100 formatx_test!("{a} {c} {b}", a = "a", b = 'b', c = 3);
101 }
102
103 #[test]
104 fn intermixed() {
105 formatx_test!("{name} {}", 1, name = 2);
106 }
107
108 #[test]
109 fn width() {
110 formatx_test!("Hello {:5}!", "x");
111 formatx_test!("Hello {:05}!", -5);
112 }
113
114 #[test]
115 fn zero_width() {
116 formatx_test!("{:04}", 42);
117 formatx_test!("Hello {:05}!", 5);
118 }
119
120 #[test]
121 fn align() {
122 formatx_test!("Hello {:<5}!", "x");
123 formatx_test!("Hello {:-<5}!", "x");
124 formatx_test!("Hello {:^5}!", "x");
125 formatx_test!("Hello {:>5}!", "x");
126 }
127
128 #[test]
129 fn sign() {
130 formatx_test!("Hello {:+}!", 5)
131 }
132
133 #[test]
134 fn precision() {
135 formatx_test!("Hello {0} is {1:.5}", "x", 0.01)
136 }
137
138 #[test]
139 fn escaping() {
140 assert_eq!(formatx!("Hello {{}}").unwrap(), format!("Hello {{}}"));
141 assert_eq!(formatx!("{{ Hello").unwrap(), format!("{{ Hello"));
142 }
143
144 #[test]
145 fn debug() {
146 formatx_test!("{} {:?}", 3, 4);
147 formatx_test!("{} {:?}", 'a', 'b');
148 formatx_test!("{} {:?}", "foo\n", "bar\n");
149 }
150
151 #[test]
152 fn trailing_commas() {
153 formatx_test!("Hello",);
154 formatx_test!("Hello {}", "world",);
155 formatx_test!("Hello {1} {0}", "1", "0",);
156 formatx_test!("Hello {name}", name = "John",);
157 }
158}