rtcm_rs/util/
array_string.rs1use 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}