1 | use std::borrow::Cow; |
2 | use std::str::FromStr; |
3 | |
4 | use crate::encode::{to_string_repr, StringStyle}; |
5 | use crate::parser; |
6 | use crate::parser::key::is_unquoted_char; |
7 | use crate::repr::{Decor, Repr}; |
8 | use crate::InternalString; |
9 | |
10 | /// Key as part of a Key/Value Pair or a table header. |
11 | /// |
12 | /// # Examples |
13 | /// |
14 | /// ```notrust |
15 | /// [dependencies."nom"] |
16 | /// version = "5.0" |
17 | /// 'literal key' = "nonsense" |
18 | /// "basic string key" = 42 |
19 | /// ``` |
20 | /// |
21 | /// There are 3 types of keys: |
22 | /// |
23 | /// 1. Bare keys (`version` and `dependencies`) |
24 | /// |
25 | /// 2. Basic quoted keys (`"basic string key"` and `"nom"`) |
26 | /// |
27 | /// 3. Literal quoted keys (`'literal key'`) |
28 | /// |
29 | /// For details see [toml spec](https://github.com/toml-lang/toml/#keyvalue-pair). |
30 | /// |
31 | /// To parse a key use `FromStr` trait implementation: `"string".parse::<Key>()`. |
32 | #[derive (Debug, Clone)] |
33 | pub struct Key { |
34 | key: InternalString, |
35 | pub(crate) repr: Option<Repr>, |
36 | pub(crate) decor: Decor, |
37 | } |
38 | |
39 | impl Key { |
40 | /// Create a new table key |
41 | pub fn new(key: impl Into<InternalString>) -> Self { |
42 | Self { |
43 | key: key.into(), |
44 | repr: None, |
45 | decor: Default::default(), |
46 | } |
47 | } |
48 | |
49 | /// Parse a TOML key expression |
50 | /// |
51 | /// Unlike `"".parse<Key>()`, this supports dotted keys. |
52 | pub fn parse(repr: &str) -> Result<Vec<Self>, crate::TomlError> { |
53 | Self::try_parse_path(repr) |
54 | } |
55 | |
56 | pub(crate) fn with_repr_unchecked(mut self, repr: Repr) -> Self { |
57 | self.repr = Some(repr); |
58 | self |
59 | } |
60 | |
61 | /// While creating the `Key`, add `Decor` to it |
62 | pub fn with_decor(mut self, decor: Decor) -> Self { |
63 | self.decor = decor; |
64 | self |
65 | } |
66 | |
67 | /// Access a mutable proxy for the `Key`. |
68 | pub fn as_mut(&mut self) -> KeyMut<'_> { |
69 | KeyMut { key: self } |
70 | } |
71 | |
72 | /// Returns the parsed key value. |
73 | pub fn get(&self) -> &str { |
74 | &self.key |
75 | } |
76 | |
77 | pub(crate) fn get_internal(&self) -> &InternalString { |
78 | &self.key |
79 | } |
80 | |
81 | /// Returns key raw representation, if available. |
82 | pub fn as_repr(&self) -> Option<&Repr> { |
83 | self.repr.as_ref() |
84 | } |
85 | |
86 | /// Returns the default raw representation. |
87 | pub fn default_repr(&self) -> Repr { |
88 | to_key_repr(&self.key) |
89 | } |
90 | |
91 | /// Returns a raw representation. |
92 | pub fn display_repr(&self) -> Cow<'_, str> { |
93 | self.as_repr() |
94 | .and_then(|r| r.as_raw().as_str()) |
95 | .map(Cow::Borrowed) |
96 | .unwrap_or_else(|| { |
97 | Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned()) |
98 | }) |
99 | } |
100 | |
101 | /// Returns the surrounding whitespace |
102 | pub fn decor_mut(&mut self) -> &mut Decor { |
103 | &mut self.decor |
104 | } |
105 | |
106 | /// Returns the surrounding whitespace |
107 | pub fn decor(&self) -> &Decor { |
108 | &self.decor |
109 | } |
110 | |
111 | /// Returns the location within the original document |
112 | #[cfg (feature = "serde" )] |
113 | pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> { |
114 | self.repr.as_ref().and_then(|r| r.span()) |
115 | } |
116 | |
117 | pub(crate) fn despan(&mut self, input: &str) { |
118 | self.decor.despan(input); |
119 | if let Some(repr) = &mut self.repr { |
120 | repr.despan(input) |
121 | } |
122 | } |
123 | |
124 | /// Auto formats the key. |
125 | pub fn fmt(&mut self) { |
126 | self.repr = Some(to_key_repr(&self.key)); |
127 | self.decor.clear(); |
128 | } |
129 | |
130 | fn try_parse_simple(s: &str) -> Result<Key, crate::TomlError> { |
131 | let mut key = parser::parse_key(s)?; |
132 | key.despan(s); |
133 | Ok(key) |
134 | } |
135 | |
136 | fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> { |
137 | let mut keys = parser::parse_key_path(s)?; |
138 | for key in &mut keys { |
139 | key.despan(s); |
140 | } |
141 | Ok(keys) |
142 | } |
143 | } |
144 | |
145 | impl std::ops::Deref for Key { |
146 | type Target = str; |
147 | |
148 | fn deref(&self) -> &Self::Target { |
149 | self.get() |
150 | } |
151 | } |
152 | |
153 | impl std::hash::Hash for Key { |
154 | fn hash<H: std::hash::Hasher>(&self, state: &mut H) { |
155 | self.get().hash(state); |
156 | } |
157 | } |
158 | |
159 | impl Ord for Key { |
160 | fn cmp(&self, other: &Self) -> std::cmp::Ordering { |
161 | self.get().cmp(other.get()) |
162 | } |
163 | } |
164 | |
165 | impl PartialOrd for Key { |
166 | fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { |
167 | Some(self.cmp(other)) |
168 | } |
169 | } |
170 | |
171 | impl Eq for Key {} |
172 | |
173 | impl PartialEq for Key { |
174 | #[inline ] |
175 | fn eq(&self, other: &Key) -> bool { |
176 | PartialEq::eq(self.get(), other:other.get()) |
177 | } |
178 | } |
179 | |
180 | impl PartialEq<str> for Key { |
181 | #[inline ] |
182 | fn eq(&self, other: &str) -> bool { |
183 | PartialEq::eq(self.get(), other) |
184 | } |
185 | } |
186 | |
187 | impl<'s> PartialEq<&'s str> for Key { |
188 | #[inline ] |
189 | fn eq(&self, other: &&str) -> bool { |
190 | PartialEq::eq(self.get(), *other) |
191 | } |
192 | } |
193 | |
194 | impl PartialEq<String> for Key { |
195 | #[inline ] |
196 | fn eq(&self, other: &String) -> bool { |
197 | PartialEq::eq(self.get(), other:other.as_str()) |
198 | } |
199 | } |
200 | |
201 | impl std::fmt::Display for Key { |
202 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
203 | crate::encode::Encode::encode(self, buf:f, input:None, ("" , "" )) |
204 | } |
205 | } |
206 | |
207 | impl FromStr for Key { |
208 | type Err = crate::TomlError; |
209 | |
210 | /// Tries to parse a key from a &str, |
211 | /// if fails, tries as basic quoted key (surrounds with "") |
212 | /// and then literal quoted key (surrounds with '') |
213 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
214 | Key::try_parse_simple(s) |
215 | } |
216 | } |
217 | |
218 | fn to_key_repr(key: &str) -> Repr { |
219 | if key.as_bytes().iter().copied().all(is_unquoted_char) && !key.is_empty() { |
220 | Repr::new_unchecked(raw:key) |
221 | } else { |
222 | to_string_repr(value:key, style:Some(StringStyle::OnelineSingle), literal:Some(false)) |
223 | } |
224 | } |
225 | |
226 | impl<'b> From<&'b str> for Key { |
227 | fn from(s: &'b str) -> Self { |
228 | Key::new(key:s) |
229 | } |
230 | } |
231 | |
232 | impl<'b> From<&'b String> for Key { |
233 | fn from(s: &'b String) -> Self { |
234 | Key::new(key:s) |
235 | } |
236 | } |
237 | |
238 | impl From<String> for Key { |
239 | fn from(s: String) -> Self { |
240 | Key::new(key:s) |
241 | } |
242 | } |
243 | |
244 | impl From<InternalString> for Key { |
245 | fn from(s: InternalString) -> Self { |
246 | Key::new(key:s) |
247 | } |
248 | } |
249 | |
250 | #[doc (hidden)] |
251 | impl From<Key> for InternalString { |
252 | fn from(key: Key) -> InternalString { |
253 | key.key |
254 | } |
255 | } |
256 | |
257 | /// A mutable reference to a `Key` |
258 | #[derive (Debug, Eq, PartialEq, PartialOrd, Ord, Hash)] |
259 | pub struct KeyMut<'k> { |
260 | key: &'k mut Key, |
261 | } |
262 | |
263 | impl<'k> KeyMut<'k> { |
264 | /// Returns the parsed key value. |
265 | pub fn get(&self) -> &str { |
266 | self.key.get() |
267 | } |
268 | |
269 | /// Returns the raw representation, if available. |
270 | pub fn as_repr(&self) -> Option<&Repr> { |
271 | self.key.as_repr() |
272 | } |
273 | |
274 | /// Returns the default raw representation. |
275 | pub fn default_repr(&self) -> Repr { |
276 | self.key.default_repr() |
277 | } |
278 | |
279 | /// Returns a raw representation. |
280 | pub fn display_repr(&self) -> Cow<str> { |
281 | self.key.display_repr() |
282 | } |
283 | |
284 | /// Returns the surrounding whitespace |
285 | pub fn decor_mut(&mut self) -> &mut Decor { |
286 | self.key.decor_mut() |
287 | } |
288 | |
289 | /// Returns the surrounding whitespace |
290 | pub fn decor(&self) -> &Decor { |
291 | self.key.decor() |
292 | } |
293 | |
294 | /// Auto formats the key. |
295 | pub fn fmt(&mut self) { |
296 | self.key.fmt() |
297 | } |
298 | } |
299 | |
300 | impl<'k> std::ops::Deref for KeyMut<'k> { |
301 | type Target = str; |
302 | |
303 | fn deref(&self) -> &Self::Target { |
304 | self.get() |
305 | } |
306 | } |
307 | |
308 | impl<'s> PartialEq<str> for KeyMut<'s> { |
309 | #[inline ] |
310 | fn eq(&self, other: &str) -> bool { |
311 | PartialEq::eq(self.get(), other) |
312 | } |
313 | } |
314 | |
315 | impl<'s> PartialEq<&'s str> for KeyMut<'s> { |
316 | #[inline ] |
317 | fn eq(&self, other: &&str) -> bool { |
318 | PartialEq::eq(self.get(), *other) |
319 | } |
320 | } |
321 | |
322 | impl<'s> PartialEq<String> for KeyMut<'s> { |
323 | #[inline ] |
324 | fn eq(&self, other: &String) -> bool { |
325 | PartialEq::eq(self.get(), other:other.as_str()) |
326 | } |
327 | } |
328 | |
329 | impl<'k> std::fmt::Display for KeyMut<'k> { |
330 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
331 | std::fmt::Display::fmt(&self.key, f) |
332 | } |
333 | } |
334 | |