1 | use std::borrow::Borrow; |
2 | use std::str::FromStr; |
3 | |
4 | /// Opaque string storage internal to `toml_edit` |
5 | #[derive (Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
6 | pub struct InternalString(Inner); |
7 | |
8 | #[cfg (feature = "kstring" )] |
9 | type Inner = kstring::KString; |
10 | #[cfg (not(feature = "kstring" ))] |
11 | type Inner = String; |
12 | |
13 | impl InternalString { |
14 | /// Create an empty string |
15 | pub fn new() -> Self { |
16 | InternalString(Inner::new()) |
17 | } |
18 | |
19 | /// Access the underlying string |
20 | #[inline ] |
21 | pub fn as_str(&self) -> &str { |
22 | self.0.as_str() |
23 | } |
24 | } |
25 | |
26 | impl std::fmt::Debug for InternalString { |
27 | #[inline ] |
28 | fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { |
29 | self.0.fmt(formatter) |
30 | } |
31 | } |
32 | |
33 | impl std::ops::Deref for InternalString { |
34 | type Target = str; |
35 | |
36 | #[inline ] |
37 | fn deref(&self) -> &str { |
38 | self.as_str() |
39 | } |
40 | } |
41 | |
42 | impl Borrow<str> for InternalString { |
43 | #[inline ] |
44 | fn borrow(&self) -> &str { |
45 | self.as_str() |
46 | } |
47 | } |
48 | |
49 | impl AsRef<str> for InternalString { |
50 | #[inline ] |
51 | fn as_ref(&self) -> &str { |
52 | self.as_str() |
53 | } |
54 | } |
55 | |
56 | impl From<&str> for InternalString { |
57 | #[inline ] |
58 | fn from(s: &str) -> Self { |
59 | #[cfg (feature = "kstring" )] |
60 | let inner = kstring::KString::from_ref(s); |
61 | #[cfg (not(feature = "kstring" ))] |
62 | let inner: String = String::from(s); |
63 | |
64 | InternalString(inner) |
65 | } |
66 | } |
67 | |
68 | impl From<String> for InternalString { |
69 | #[inline ] |
70 | fn from(s: String) -> Self { |
71 | #[allow (clippy::useless_conversion)] // handle any string type |
72 | InternalString(s.into()) |
73 | } |
74 | } |
75 | |
76 | impl From<&String> for InternalString { |
77 | #[inline ] |
78 | fn from(s: &String) -> Self { |
79 | InternalString(s.into()) |
80 | } |
81 | } |
82 | |
83 | impl From<&InternalString> for InternalString { |
84 | #[inline ] |
85 | fn from(s: &InternalString) -> Self { |
86 | s.clone() |
87 | } |
88 | } |
89 | |
90 | impl From<Box<str>> for InternalString { |
91 | #[inline ] |
92 | fn from(s: Box<str>) -> Self { |
93 | InternalString(s.into()) |
94 | } |
95 | } |
96 | |
97 | impl FromStr for InternalString { |
98 | type Err = core::convert::Infallible; |
99 | #[inline ] |
100 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
101 | Ok(Self::from(s)) |
102 | } |
103 | } |
104 | |
105 | impl std::fmt::Display for InternalString { |
106 | #[inline ] |
107 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
108 | self.as_str().fmt(f) |
109 | } |
110 | } |
111 | |
112 | #[cfg (feature = "serde" )] |
113 | impl serde::Serialize for InternalString { |
114 | #[inline ] |
115 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> |
116 | where |
117 | S: serde::Serializer, |
118 | { |
119 | serializer.serialize_str(self.as_str()) |
120 | } |
121 | } |
122 | |
123 | #[cfg (feature = "serde" )] |
124 | impl<'de> serde::Deserialize<'de> for InternalString { |
125 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> |
126 | where |
127 | D: serde::Deserializer<'de>, |
128 | { |
129 | deserializer.deserialize_string(StringVisitor) |
130 | } |
131 | } |
132 | |
133 | #[cfg (feature = "serde" )] |
134 | struct StringVisitor; |
135 | |
136 | #[cfg (feature = "serde" )] |
137 | impl<'de> serde::de::Visitor<'de> for StringVisitor { |
138 | type Value = InternalString; |
139 | |
140 | fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
141 | formatter.write_str("a string" ) |
142 | } |
143 | |
144 | fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> |
145 | where |
146 | E: serde::de::Error, |
147 | { |
148 | Ok(InternalString::from(v)) |
149 | } |
150 | |
151 | fn visit_string<E>(self, v: String) -> Result<Self::Value, E> |
152 | where |
153 | E: serde::de::Error, |
154 | { |
155 | Ok(InternalString::from(v)) |
156 | } |
157 | |
158 | fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> |
159 | where |
160 | E: serde::de::Error, |
161 | { |
162 | match std::str::from_utf8(v) { |
163 | Ok(s) => Ok(InternalString::from(s)), |
164 | Err(_) => Err(serde::de::Error::invalid_value( |
165 | serde::de::Unexpected::Bytes(v), |
166 | &self, |
167 | )), |
168 | } |
169 | } |
170 | |
171 | fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> |
172 | where |
173 | E: serde::de::Error, |
174 | { |
175 | match String::from_utf8(v) { |
176 | Ok(s) => Ok(InternalString::from(s)), |
177 | Err(e) => Err(serde::de::Error::invalid_value( |
178 | serde::de::Unexpected::Bytes(&e.into_bytes()), |
179 | &self, |
180 | )), |
181 | } |
182 | } |
183 | } |
184 | |