1use core::fmt;
2use core::ops::Deref;
3
4use arrayvec::ArrayString;
5
6const MAX_DEC_LEN: usize = 8;
7pub(crate) const MAX_ERR_LEN: usize = 256;
8const MAX_INF_LEN: usize = 128;
9pub(crate) const MAX_MIN_LEN: usize = 8;
10const MAX_NAN_LEN: usize = 64;
11const MAX_PLUS_LEN: usize = 8;
12pub(crate) const MAX_SEP_LEN: usize = 8;
13
14#[cfg(feature = "with-serde")]
15use serde::{de, ser};
16
17use crate::error::Error;
18
19#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
22pub struct DecimalStr<'a>(&'a str);
23
24impl<'a> DecimalStr<'a> {
25 pub fn new(s: &'a str) -> Result<DecimalStr<'a>, Error> {
34 Self::_new(s)
35 }
36}
37
38#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
41pub struct InfinityStr<'a>(&'a str);
42
43impl<'a> InfinityStr<'a> {
44 pub fn new(s: &'a str) -> Result<InfinityStr<'a>, Error> {
53 Self::_new(s)
54 }
55}
56
57#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
60pub struct MinusSignStr<'a>(&'a str);
61
62impl<'a> MinusSignStr<'a> {
63 pub fn new(s: &'a str) -> Result<MinusSignStr<'a>, Error> {
72 Self::_new(s)
73 }
74}
75
76#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
79pub struct NanStr<'a>(&'a str);
80
81impl<'a> NanStr<'a> {
82 pub fn new(s: &'a str) -> Result<NanStr<'a>, Error> {
91 Self::_new(s)
92 }
93}
94
95#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
98pub struct PlusSignStr<'a>(&'a str);
99
100impl<'a> PlusSignStr<'a> {
101 pub fn new(s: &'a str) -> Result<PlusSignStr<'a>, Error> {
110 Self::_new(s)
111 }
112}
113
114#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
117pub struct SeparatorStr<'a>(&'a str);
118
119impl<'a> SeparatorStr<'a> {
120 pub fn new(s: &'a str) -> Result<SeparatorStr<'a>, Error> {
129 Self::_new(s)
130 }
131}
132
133macro_rules! create_impls {
134 ( $name:ident, $max_len:expr ) => {
135 impl<'a> $name<'a> {
136 #[inline(always)]
137 pub fn into_str(self) -> &'a str {
139 self.0
140 }
141
142 #[inline(always)]
143 fn _new(s: &'a str) -> Result<$name<'a>, Error> {
144 let len = s.len();
145 if len > $max_len {
146 return Err(Error::capacity(len, $max_len));
147 }
148 Ok($name(s))
149 }
150 }
151
152 impl<'a> AsRef<str> for $name<'a> {
153 #[inline(always)]
154 fn as_ref(&self) -> &str {
155 self.0
156 }
157 }
158
159 impl<'a> fmt::Debug for $name<'a> {
160 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
161 write!(f, "{:?}", self.0)
162 }
163 }
164
165 impl<'a> fmt::Display for $name<'a> {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 write!(f, "{}", self.0)
168 }
169 }
170 };
171}
172
173create_impls!(DecimalStr, MAX_DEC_LEN);
174create_impls!(InfinityStr, MAX_INF_LEN);
175create_impls!(MinusSignStr, MAX_MIN_LEN);
176create_impls!(NanStr, MAX_NAN_LEN);
177create_impls!(PlusSignStr, MAX_PLUS_LEN);
178create_impls!(SeparatorStr, MAX_SEP_LEN);
179
180macro_rules! create_string {
181 ( $name:ident, $visitor:ident, $max_len:expr ) => {
182 #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
183 pub(crate) struct $name(ArrayString<$max_len>);
184
185 impl $name {
186 #[allow(dead_code)]
187 pub(crate) fn new<S>(s: S) -> Result<Self, Error>
188 where
189 S: AsRef<str>,
190 {
191 let s = s.as_ref();
192 let a = ArrayString::from(s).map_err(|_| Error::capacity(s.len(), $max_len))?;
193 Ok($name(a))
194 }
195
196 #[allow(dead_code)]
197 pub(crate) fn truncated<S>(s: S) -> Self
198 where
199 S: AsRef<str>,
200 {
201 let s = s.as_ref();
202 let s = if s.len() > $max_len {
203 &s[0..$max_len]
204 } else {
205 s
206 };
207 $name(ArrayString::from(s).unwrap())
208 }
209
210 #[allow(dead_code)]
211 #[inline(always)]
212 pub(crate) fn capacity() -> usize {
213 $max_len
214 }
215 }
216
217 impl Deref for $name {
218 type Target = str;
219
220 #[inline(always)]
221 fn deref(&self) -> &str {
222 self.0.deref()
223 }
224 }
225
226 impl fmt::Display for $name {
227 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 write!(f, "{}", self.0)
229 }
230 }
231
232 impl From<$name> for ArrayString<$max_len> {
233 fn from(s: $name) -> Self {
234 s.0
235 }
236 }
237
238 #[cfg(feature = "with-serde")]
239 impl ser::Serialize for $name {
240 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
241 where
242 S: ser::Serializer,
243 {
244 serializer.serialize_str(self.0.as_str())
245 }
246 }
247
248 #[cfg(feature = "with-serde")]
249 struct $visitor;
250
251 #[cfg(feature = "with-serde")]
252 impl<'de> de::Visitor<'de> for $visitor {
253 type Value = $name;
254
255 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
256 write!(formatter, "a string containing at most {} bytes", $max_len)
257 }
258
259 fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
260 where
261 E: de::Error,
262 {
263 $name::new(s).map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &self))
264 }
265 }
266
267 #[cfg(feature = "with-serde")]
268 impl<'de> de::Deserialize<'de> for $name {
269 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
270 where
271 D: de::Deserializer<'de>,
272 {
273 deserializer.deserialize_str($visitor)
274 }
275 }
276 };
277}
278
279create_string!(DecString, DecVisitor, MAX_DEC_LEN);
280create_string!(ErrString, ErrVisitor, MAX_ERR_LEN);
281create_string!(InfString, InfVisitor, MAX_INF_LEN);
282create_string!(MinString, MinVisitor, MAX_MIN_LEN);
283create_string!(NanString, NanVisitor, MAX_NAN_LEN);
284create_string!(PlusString, PlusVisitor, MAX_PLUS_LEN);
285create_string!(SepString, SepVisitor, MAX_SEP_LEN);