1#[macro_export]
73macro_rules! scale_fn {
74 (
75 $name:ident,
76 base: $base_arg:ident,
77 constraint: $constraint_arg:ident,
78 mantissa_fmt: $mantissa_fmt:expr,
79 unit: $unit_arg:literal,
80 doc: $doc_arg:literal
81 ) => {
82 #[doc=$doc_arg]
83 pub fn $name<F>(x: F) -> String
84 where
85 F: Into<f64>,
86 {
87 let value = $crate::value::Value::new_with(
88 x,
89 $crate::base::Base::$base_arg,
90 $crate::prefix::Constraint::$constraint_arg,
91 );
92 format!(
93 "{}{}",
94 $crate::format_value!(value, $mantissa_fmt),
95 $unit_arg
96 )
97 }
98 };
99
100 (
101 $name:ident,
102 base: $base_arg:ident,
103 constraint: $constraint_arg:ident,
104 mantissa_fmt: $mantissa_fmt:expr,
105 groupings: $sep_arg:literal,
106 unit: $unit_arg:literal,
107 doc: $doc_arg:literal
108 ) => {
109 #[doc=$doc_arg]
110 pub fn $name<F>(x: F) -> String
111 where
112 F: Into<f64>,
113 {
114 let value = $crate::value::Value::new_with(
115 x,
116 $crate::base::Base::$base_arg,
117 $crate::prefix::Constraint::$constraint_arg,
118 );
119 format!(
120 "{}{}",
121 $crate::format_value!(value, $mantissa_fmt, groupings: $sep_arg),
122 $unit_arg
123 )
124 }
125 };
126
127 (
128 $name:ident,
129 base: $base_arg:ident,
130 constraint: $constraint_arg:ident,
131 mantissa_fmt: $mantissa_fmt:expr,
132 groupings: $sep_arg:literal,
133 doc: $doc_arg:literal
134 ) => {
135 #[doc=$doc_arg]
136 pub fn $name<F>(x: F) -> String
137 where
138 F: Into<f64>,
139 {
140 let value = $crate::value::Value::new_with(
141 x,
142 $crate::base::Base::$base_arg,
143 $crate::prefix::Constraint::$constraint_arg,
144 );
145 format!(
146 "{}",
147 $crate::format_value!(value, $mantissa_fmt, groupings: $sep_arg, no_unit)
148 )
149 }
150 };
151}
152
153scale_fn!(number_,
154 base: B1000,
155 constraint: UnitOnly,
156 mantissa_fmt: "{}",
157 groupings: '_',
158 doc: "Print a number without units.");
159
160scale_fn!(seconds,
161 base: B1000,
162 constraint: UnitAndBelow,
163 mantissa_fmt: "{}",
164 unit: "s",
165 doc: "Print a value in seconds.");
166
167scale_fn!(seconds3,
168 base: B1000,
169 constraint: UnitAndBelow,
170 mantissa_fmt: "{:.3}",
171 unit: "s",
172 doc: "Print a value in seconds with 3 decimals.");
173
174scale_fn!(bytes,
175 base: B1000,
176 constraint: UnitAndAbove,
177 mantissa_fmt: "{}",
178 unit: "B",
179 doc: "Print a value in bytes.");
180
181scale_fn!(bytes_,
182 base: B1000,
183 constraint: UnitOnly,
184 mantissa_fmt: "{}",
185 groupings: '_',
186 unit: "B",
187 doc: "Print a value in bytes with thousands separator.");
188
189scale_fn!(bytes1,
190 base: B1000,
191 constraint: UnitAndAbove,
192 mantissa_fmt: "{:.1}",
193 unit: "B",
194 doc: "Print a value in bytes with 1 decimal.");
195
196scale_fn!(bytes2,
197 base: B1000,
198 constraint: UnitAndAbove,
199 mantissa_fmt: "{:.2}",
200 unit: "B",
201 doc: "Print a value in bytes with 2 decimals.");
202
203scale_fn!(bibytes,
204 base: B1024,
205 constraint: UnitAndAbove,
206 mantissa_fmt: "{}",
207 unit: "B",
208 doc: "Print a value in bibytes.");
209
210scale_fn!(bibytes1,
211 base: B1024,
212 constraint: UnitAndAbove,
213 mantissa_fmt: "{:.1}",
214 unit: "B",
215 doc: "Print a value in bibytes with 1 decimal.");
216
217scale_fn!(bibytes2,
218 base: B1024,
219 constraint: UnitAndAbove,
220 mantissa_fmt: "{:.2}",
221 unit: "B",
222 doc: "Print a value in bibytes with 2 decimals.");
223
224#[cfg(test)]
225mod tests {
226 use super::*;
227
228 #[test]
229 fn test_number_() {
230 let actual = format!("result is {}", number_(1234.5678));
231 let expected = "result is 1_234.567_8";
232 assert_eq!(actual, expected);
233
234 let actual = format!("result is {:>10}", number_(12.4e-8));
235 let expected = "result is 0.000_000_124";
236 assert_eq!(actual, expected);
237
238 let actual = format!("result is {}", number_(1.1));
239 let expected = "result is 1.1";
240 assert_eq!(actual, expected);
241
242 let actual = format!("result is {}", number_(1.0));
243 let expected = "result is 1";
244 assert_eq!(actual, expected);
245 }
246
247 #[test]
248 fn test_seconds() {
249 let actual = format!("result is {}", seconds(1234.5678));
250 let expected = "result is 1234.5678 s";
251 assert_eq!(actual, expected);
252
253 let actual = format!("result is {:>10}", seconds(12.4e-7));
254 let expected = "result is 1.24 µs";
255 assert_eq!(actual, expected);
256
257 let actual = format!("result is {}", seconds(12e-7));
258 let expected = "result is 1.2 µs";
259 assert_eq!(actual, expected);
260
261 let actual = format!("result is {}", seconds(1.0));
262 let expected = "result is 1 s";
263 assert_eq!(actual, expected);
264 }
265
266 #[test]
267 fn test_seconds3() {
268 let actual = format!("result is {}", seconds3(1234.5678));
269 let expected = "result is 1234.568 s";
270 assert_eq!(actual, expected);
271
272 let actual = format!("result is {:>10}", seconds3(12.4e-7));
273 let expected = "result is 1.240 µs";
274 assert_eq!(actual, expected);
275
276 let actual = format!("result is {}", seconds3(12e-7));
277 let expected = "result is 1.200 µs";
278 assert_eq!(actual, expected);
279
280 let actual = format!("result is {}", seconds3(1.0));
281 let expected = "result is 1.000 s";
282 assert_eq!(actual, expected);
283 }
284
285 #[test]
286 fn test_bytes() {
287 let actual = format!("result is {}", bytes(12_345_678));
288 let expected = "result is 12.345678 MB";
289 assert_eq!(actual, expected);
290
291 let actual = format!("result is {:>10}", bytes(16));
292 let expected = "result is 16 B";
293 assert_eq!(actual, expected);
294
295 let actual = format!("result is {}", bytes(0.123456));
296 let expected = "result is 0.123456 B";
297 assert_eq!(actual, expected);
298 }
299
300 #[test]
301 fn test_bytes_() {
302 let actual = format!("result is {}", bytes_(12_345_678));
303 let expected = "result is 12_345_678 B";
304 assert_eq!(actual, expected);
305
306 let actual = format!("result is {:>10}", bytes_(16));
307 let expected = "result is 16 B";
308 assert_eq!(actual, expected);
309
310 let actual = format!("result is {}", bytes_(0.123456));
311 let expected = "result is 0.123_456 B";
312 assert_eq!(actual, expected);
313 }
314
315 #[test]
316 fn test_bytes1() {
317 let actual = format!("result is {}", bytes1(12_345_678));
318 let expected = "result is 12.3 MB";
319 assert_eq!(actual, expected);
320
321 let actual = format!("result is {:>10}", bytes1(16));
322 let expected = "result is 16.0 B";
323 assert_eq!(actual, expected);
324
325 let actual = format!("result is {}", bytes1(0.12));
326 let expected = "result is 0.1 B";
327 assert_eq!(actual, expected);
328 }
329
330 #[test]
331 fn test_bibytes() {
332 let actual = format!("result is {}", bibytes(11.8 * (1024 * 1024) as f64));
333 let expected = "result is 11.8 MiB";
334 assert_eq!(actual, expected);
335
336 let actual = format!("result is {}", bibytes(16 * 1024));
337 let expected = "result is 16 kiB";
338 assert_eq!(actual, expected);
339
340 let actual = format!("result is {:>10}", bibytes(16));
341 let expected = "result is 16 B";
342 assert_eq!(actual, expected);
343
344 let actual = format!("result is {}", bibytes(0.123456));
345 let expected = "result is 0.123456 B";
346 assert_eq!(actual, expected);
347 }
348
349 #[test]
350 fn test_bibytes1() {
351 let actual = format!("result is {}", bibytes1(12_345_678));
352 let expected = "result is 11.8 MiB";
353 assert_eq!(actual, expected);
354
355 let actual = format!("result is {}", bibytes1(16 * 1024));
356 let expected = "result is 16.0 kiB";
357 assert_eq!(actual, expected);
358
359 let actual = format!("result is {:>10}", bibytes1(16));
360 let expected = "result is 16.0 B";
361 assert_eq!(actual, expected);
362
363 let actual = format!("result is {}", bibytes1(0.12));
364 let expected = "result is 0.1 B";
365 assert_eq!(actual, expected);
366 }
367
368 #[test]
369 fn test_issue_8() {
370 let actual = format!("result is {}", seconds3(178.844052305));
371 let expected = "result is 178.844 s";
372 assert_eq!(actual, expected);
373
374 let actual = format!("result is {}", seconds3(83.99999999999999e-9));
375 let expected = "result is 84.000 ns";
376 assert_eq!(actual, expected);
377 }
378}