Skip to main content

nekolib/utils/
output.rs

1//! 形式つき出力。
2
3/// 形式つき出力(スペース区切り)。
4///
5/// # Examples
6/// ```
7/// use nekolib::utils::{SpaceSep, StrSep, PerLine};
8///
9/// let a = vec![13, 5, 30, 27, 6];
10/// let b = vec!['a', 'b', 'c'];
11///
12/// assert_eq!(format!("{}", SpaceSep(&a)), "13 5 30 27 6");
13/// assert_eq!(format!("{:02}", SpaceSep(&a)), "13 05 30 27 06");
14/// assert_eq!(format!("{:#04x}", SpaceSep(&a[..3])), "0x0d 0x05 0x1e");
15/// assert_eq!(format!("{:?}", SpaceSep(&b)), "'a' 'b' 'c'");
16/// assert_eq!(format!("{}", PerLine(&b)), "a\nb\nc");
17/// assert_eq!(format!("{:2}", StrSep(&a, ", ")), "13,  5, 30, 27,  6");
18/// ```
19pub struct SpaceSep<'a, D: ?Sized>(pub &'a D);
20
21/// 形式つき出力(改行区切り)。
22///
23/// # Examples
24/// ```
25/// use nekolib::utils::{SpaceSep, StrSep, PerLine};
26///
27/// let a = vec![13, 5, 30, 27, 6];
28/// let b = vec!['a', 'b', 'c'];
29///
30/// assert_eq!(format!("{}", SpaceSep(&a)), "13 5 30 27 6");
31/// assert_eq!(format!("{:02}", SpaceSep(&a)), "13 05 30 27 06");
32/// assert_eq!(format!("{:#04x}", SpaceSep(&a[..3])), "0x0d 0x05 0x1e");
33/// assert_eq!(format!("{:?}", SpaceSep(&b)), "'a' 'b' 'c'");
34/// assert_eq!(format!("{}", PerLine(&b)), "a\nb\nc");
35/// assert_eq!(format!("{:2}", StrSep(&a, ", ")), "13,  5, 30, 27,  6");
36/// ```
37pub struct PerLine<'a, D: ?Sized>(pub &'a D);
38
39/// 形式つき出力(任意文字列区切り)。
40///
41/// # Examples
42/// ```
43/// use nekolib::utils::{SpaceSep, StrSep, PerLine};
44///
45/// let a = vec![13, 5, 30, 27, 6];
46/// let b = vec!['a', 'b', 'c'];
47///
48/// assert_eq!(format!("{}", SpaceSep(&a)), "13 5 30 27 6");
49/// assert_eq!(format!("{:02}", SpaceSep(&a)), "13 05 30 27 06");
50/// assert_eq!(format!("{:#04x}", SpaceSep(&a[..3])), "0x0d 0x05 0x1e");
51/// assert_eq!(format!("{:?}", SpaceSep(&b)), "'a' 'b' 'c'");
52/// assert_eq!(format!("{}", PerLine(&b)), "a\nb\nc");
53/// assert_eq!(format!("{:2}", StrSep(&a, ", ")), "13,  5, 30, 27,  6");
54/// ```
55pub struct StrSep<'a, D: ?Sized>(pub &'a D, pub &'a str);
56
57use std::fmt;
58
59macro_rules! impl_fmt {
60    ( $( ($fmt:ident, $fn:ident), )* ) => { $(
61        fn $fn<I>(it: I, sep: &str, f: &mut fmt::Formatter) -> fmt::Result
62        where
63            I: IntoIterator,
64            <I as IntoIterator>::Item: fmt::$fmt,
65        {
66            for (i, x) in it.into_iter().enumerate() {
67                if i > 0 {
68                    write!(f, "{}", sep)?;
69                }
70                fmt::$fmt::fmt(&x, f)?;
71            }
72            Ok(())
73        }
74
75        impl<'a, D: 'a> fmt::$fmt for SpaceSep<'a, D>
76        where
77            D: ?Sized,
78            &'a D: IntoIterator,
79            <&'a D as IntoIterator>::Item: fmt::$fmt,
80        {
81            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
82                $fn(self.0, " ", f)
83            }
84        }
85
86        impl<'a, D: 'a> fmt::$fmt for PerLine<'a, D>
87        where
88            D: ?Sized,
89            &'a D: IntoIterator,
90            <&'a D as IntoIterator>::Item: fmt::$fmt,
91        {
92            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
93                $fn(self.0, "\n", f)
94            }
95        }
96
97        impl<'a, D: 'a> fmt::$fmt for StrSep<'a, D>
98        where
99            D: ?Sized,
100            &'a D: IntoIterator,
101            <&'a D as IntoIterator>::Item: fmt::$fmt,
102        {
103            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104                $fn(self.0, self.1, f)
105            }
106        }
107)* };
108}
109
110impl_fmt! {
111    (Display, join_display),
112    (Debug, join_debug),
113    (Octal, join_octal),
114    (LowerHex, join_lower_hex),
115    (UpperHex, join_upper_hex),
116    (Pointer, join_pointer),
117    (Binary, join_binary),
118    (LowerExp, join_lower_exp),
119    (UpperExp, join_upper_exp),
120}