num_format/
custom_format_builder.rs

1use crate::custom_format::CustomFormat;
2use crate::error::Error;
3use crate::format::Format;
4use crate::grouping::Grouping;
5use crate::locale::Locale;
6use crate::strings::{DecString, InfString, MinString, NanString, PlusString, SepString};
7
8/// Type for building [`CustomFormat`]s.
9///
10/// [`CustomFormat`]: struct.CustomFormat.html
11#[derive(Clone, Debug, Eq, PartialEq, Hash)]
12#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))]
13pub struct CustomFormatBuilder {
14    dec: Result<DecString, Error>,
15    grp: Grouping,
16    inf: Result<InfString, Error>,
17    min: Result<MinString, Error>,
18    nan: Result<NanString, Error>,
19    plus: Result<PlusString, Error>,
20    sep: Result<SepString, Error>,
21}
22
23impl CustomFormatBuilder {
24    pub(crate) fn new() -> Self {
25        Self {
26            dec: DecString::new(Locale::en.decimal()),
27            grp: Locale::en.grouping(),
28            inf: InfString::new(Locale::en.infinity()),
29            min: MinString::new(Locale::en.minus_sign()),
30            nan: NanString::new(Locale::en.nan()),
31            plus: PlusString::new(Locale::en.plus_sign()),
32            sep: SepString::new(Locale::en.separator()),
33        }
34    }
35
36    /// Construct a [`CustomFormat`].
37    ///
38    /// # Errors
39    ///
40    /// Return an error if:
41    /// - The "decimal" is longer than 8 bytes
42    /// - The "infinity sign" is longer than 128 bytes
43    /// - The "minus sign" is longer than 8 bytes
44    /// - The "nan symbol" is longer than 64 bytes
45    /// - The "plus sign" is longer than 8 bytes
46    /// - The "separator" is longer than 8 bytes
47    ///
48    /// [`CustomFormat`]: struct.CustomFormat.html
49    pub fn build(self) -> Result<CustomFormat, Error> {
50        Ok(CustomFormat {
51            dec: self.dec?,
52            grp: self.grp,
53            inf: self.inf?,
54            min: self.min?,
55            nan: self.nan?,
56            plus: self.plus?,
57            sep: self.sep?,
58        })
59    }
60
61    /// Sets the character used to represent decimal points.
62    pub fn decimal<S>(mut self, s: S) -> Self
63    where
64        S: AsRef<str>,
65    {
66        self.dec = DecString::new(s);
67        self
68    }
69
70    /// Sets all fields based on the provided format.
71    pub fn format<F>(mut self, value: &F) -> Self
72    where
73        F: Format,
74    {
75        self.dec = DecString::new(value.decimal());
76        self.grp = value.grouping();
77        self.inf = InfString::new(value.infinity());
78        self.min = MinString::new(value.minus_sign());
79        self.nan = NanString::new(value.nan());
80        self.plus = PlusString::new(value.plus_sign());
81        self.sep = SepString::new(value.separator());
82        self
83    }
84
85    /// Sets the [`Grouping`] used to separate digits.
86    ///
87    /// [`Grouping`]: enum.Grouping.html
88    pub fn grouping(mut self, value: Grouping) -> Self {
89        self.grp = value;
90        self
91    }
92
93    /// Sets the string representation of infinity.
94    pub fn infinity<S>(mut self, s: S) -> Self
95    where
96        S: AsRef<str>,
97    {
98        self.inf = InfString::new(s);
99        self
100    }
101
102    /// Sets the string representation of a minus sign.
103    pub fn minus_sign<S>(mut self, s: S) -> Self
104    where
105        S: AsRef<str>,
106    {
107        self.min = MinString::new(s);
108        self
109    }
110
111    /// Sets the string representation of NaN.
112    pub fn nan<S>(mut self, s: S) -> Self
113    where
114        S: AsRef<str>,
115    {
116        self.nan = NanString::new(s);
117        self
118    }
119
120    /// Sets the string representation of a plus sign.
121    pub fn plus_sign<S>(mut self, s: S) -> Self
122    where
123        S: AsRef<str>,
124    {
125        self.plus = PlusString::new(s);
126        self
127    }
128
129    /// Sets the string representation of a thousands separator.
130    pub fn separator<S>(mut self, s: S) -> Self
131    where
132        S: AsRef<str>,
133    {
134        self.sep = SepString::new(s);
135        self
136    }
137}
138
139impl From<CustomFormat> for CustomFormatBuilder {
140    fn from(format: CustomFormat) -> Self {
141        CustomFormat::builder().format(&format)
142    }
143}
144
145impl From<Locale> for CustomFormatBuilder {
146    fn from(locale: Locale) -> Self {
147        CustomFormat::builder().format(&locale)
148    }
149}
150
151#[cfg(all(feature = "with-system-locale", any(unix, windows)))]
152mod standard {
153    use super::*;
154    use crate::system_locale::SystemLocale;
155
156    impl From<SystemLocale> for CustomFormatBuilder {
157        fn from(locale: SystemLocale) -> Self {
158            CustomFormat::builder().format(&locale)
159        }
160    }
161}