rtcm_rs/util/
array_string.rs

1use crate::tinyvec::ArrayVec;
2#[cfg(feature = "serde")]
3use crate::{Deserialize, Serialize, Visitor};
4use core::ops::Deref;
5
6#[derive(Default, Clone, PartialEq)]
7pub struct ArrayString<const N: usize> {
8    vec: ArrayVec<[u8; N]>,
9}
10
11impl<const N: usize> ArrayString<N> {
12    pub fn new() -> Self {
13        let vec = ArrayVec::<[u8; N]>::new();
14        ArrayString { vec }
15    }
16    #[inline]
17    pub fn try_push(&mut self, ch: char) -> Result<(), ()> {
18        let len = ch.len_utf8();
19        if self.vec.len() + len > self.vec.capacity() {
20            return Err(());
21        }
22        match len {
23            1 => self.vec.push(ch as u8),
24            _ => self
25                .vec
26                .extend_from_slice(ch.encode_utf8(&mut [0; 4]).as_bytes()),
27        }
28        Ok(())
29    }
30}
31
32impl<const N: usize> From<&str> for ArrayString<N> {
33    fn from(value: &str) -> Self {
34        let mut array_string = ArrayString::<N>::new();
35        for ch in value.chars() {
36            if array_string.try_push(ch).is_err() {
37                break;
38            }
39        }
40        array_string
41    }
42}
43
44impl<const N: usize> Deref for ArrayString<N> {
45    type Target = str;
46
47    #[inline]
48    fn deref(&self) -> &str {
49        core::str::from_utf8(&self.vec).unwrap()
50    }
51}
52
53impl<const N: usize> AsRef<str> for ArrayString<N> {
54    #[inline]
55    fn as_ref(&self) -> &str {
56        self
57    }
58}
59
60impl<const N: usize> FromIterator<char> for ArrayString<N> {
61    fn from_iter<I: IntoIterator<Item = char>>(iter: I) -> ArrayString<N> {
62        let mut buf = ArrayString::new();
63        for c in iter.into_iter() {
64            if buf.try_push(c).is_err() {
65                break;
66            }
67        }
68        buf
69    }
70}
71
72impl<const N: usize> core::fmt::Display for ArrayString<N> {
73    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
74        write!(f, "ArrayString<{}>(\"", N)?;
75        f.write_str(&*self)?;
76        f.write_str("\")")
77    }
78}
79impl<const N: usize> core::fmt::Debug for ArrayString<N> {
80    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
81        write!(f, "ArrayString<{}>(\"", N)?;
82        f.write_str(&*self)?;
83        f.write_str("\")")
84    }
85}
86
87#[cfg(feature = "serde")]
88impl<const N: usize> Serialize for ArrayString<N> {
89    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
90    where
91        S: sd::Serializer,
92    {
93        serializer.serialize_str(&*self)
94    }
95}
96
97#[cfg(feature = "serde")]
98impl<'de, const N: usize> Deserialize<'de> for ArrayString<N> {
99    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
100    where
101        D: sd::Deserializer<'de>,
102    {
103        struct ArrayStringVisitor<const N: usize>;
104
105        impl<'de, const N: usize> Visitor<'de> for ArrayStringVisitor<N> {
106            type Value = ArrayString<N>;
107
108            fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
109                formatter.write_str("an UTF-8 encoded string")
110            }
111
112            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
113                let mut value = ArrayString::<N>::new();
114                for ch in v.chars() {
115                    if value.try_push(ch).is_err() {
116                        break;
117                    }
118                }
119                Ok(value)
120            }
121        }
122
123        deserializer.deserialize_str(ArrayStringVisitor::<N>)
124    }
125}
126
127#[cfg(feature = "test_gen")]
128use crate::source_repr::SourceRepr;
129
130#[cfg(feature = "test_gen")]
131impl<const N: usize> SourceRepr for ArrayString<N> {
132    fn to_source(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
133        write!(f, "ArrayString::<{}>::from(\"{}\")", N, self.as_ref())
134    }
135}