1 use std::borrow::Cow;
2 use std::str::FromStr;
3 
4 use crate::repr::{Decor, Repr};
5 use crate::InternalString;
6 
7 /// Key as part of a Key/Value Pair or a table header.
8 ///
9 /// # Examples
10 ///
11 /// ```notrust
12 /// [dependencies."nom"]
13 /// version = "5.0"
14 /// 'literal key' = "nonsense"
15 /// "basic string key" = 42
16 /// ```
17 ///
18 /// There are 3 types of keys:
19 ///
20 /// 1. Bare keys (`version` and `dependencies`)
21 ///
22 /// 2. Basic quoted keys (`"basic string key"` and `"nom"`)
23 ///
24 /// 3. Literal quoted keys (`'literal key'`)
25 ///
26 /// For details see [toml spec](https://github.com/toml-lang/toml/#keyvalue-pair).
27 ///
28 /// To parse a key use `FromStr` trait implementation: `"string".parse::<Key>()`.
29 #[derive(Debug)]
30 pub struct Key {
31     key: InternalString,
32     pub(crate) repr: Option<Repr>,
33     pub(crate) leaf_decor: Decor,
34     pub(crate) dotted_decor: Decor,
35 }
36 
37 impl Key {
38     /// Create a new table key
new(key: impl Into<InternalString>) -> Self39     pub fn new(key: impl Into<InternalString>) -> Self {
40         Self {
41             key: key.into(),
42             repr: None,
43             leaf_decor: Default::default(),
44             dotted_decor: Default::default(),
45         }
46     }
47 
48     /// Parse a TOML key expression
49     ///
50     /// Unlike `"".parse<Key>()`, this supports dotted keys.
51     #[cfg(feature = "parse")]
parse(repr: &str) -> Result<Vec<Self>, crate::TomlError>52     pub fn parse(repr: &str) -> Result<Vec<Self>, crate::TomlError> {
53         Self::try_parse_path(repr)
54     }
55 
with_repr_unchecked(mut self, repr: Repr) -> Self56     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     #[deprecated(since = "0.21.1", note = "Replaced with `with_leaf_decor`")]
with_decor(self, decor: Decor) -> Self63     pub fn with_decor(self, decor: Decor) -> Self {
64         self.with_leaf_decor(decor)
65     }
66 
67     /// While creating the `Key`, add `Decor` to it for the line entry
with_leaf_decor(mut self, decor: Decor) -> Self68     pub fn with_leaf_decor(mut self, decor: Decor) -> Self {
69         self.leaf_decor = decor;
70         self
71     }
72 
73     /// While creating the `Key`, add `Decor` to it for between dots
with_dotted_decor(mut self, decor: Decor) -> Self74     pub fn with_dotted_decor(mut self, decor: Decor) -> Self {
75         self.dotted_decor = decor;
76         self
77     }
78 
79     /// Access a mutable proxy for the `Key`.
as_mut(&mut self) -> KeyMut<'_>80     pub fn as_mut(&mut self) -> KeyMut<'_> {
81         KeyMut { key: self }
82     }
83 
84     /// Returns the parsed key value.
get(&self) -> &str85     pub fn get(&self) -> &str {
86         &self.key
87     }
88 
get_internal(&self) -> &InternalString89     pub(crate) fn get_internal(&self) -> &InternalString {
90         &self.key
91     }
92 
93     /// Returns key raw representation, if available.
as_repr(&self) -> Option<&Repr>94     pub fn as_repr(&self) -> Option<&Repr> {
95         self.repr.as_ref()
96     }
97 
98     /// Returns the default raw representation.
99     #[cfg(feature = "display")]
default_repr(&self) -> Repr100     pub fn default_repr(&self) -> Repr {
101         to_key_repr(&self.key)
102     }
103 
104     /// Returns a raw representation.
105     #[cfg(feature = "display")]
display_repr(&self) -> Cow<'_, str>106     pub fn display_repr(&self) -> Cow<'_, str> {
107         self.as_repr()
108             .and_then(|r| r.as_raw().as_str())
109             .map(Cow::Borrowed)
110             .unwrap_or_else(|| {
111                 Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned())
112             })
113     }
114 
115     /// Returns the surrounding whitespace
116     #[deprecated(since = "0.21.1", note = "Replaced with `decor_mut`")]
decor_mut(&mut self) -> &mut Decor117     pub fn decor_mut(&mut self) -> &mut Decor {
118         self.leaf_decor_mut()
119     }
120 
121     /// Returns the surrounding whitespace for the line entry
leaf_decor_mut(&mut self) -> &mut Decor122     pub fn leaf_decor_mut(&mut self) -> &mut Decor {
123         &mut self.leaf_decor
124     }
125 
126     /// Returns the surrounding whitespace for between dots
dotted_decor_mut(&mut self) -> &mut Decor127     pub fn dotted_decor_mut(&mut self) -> &mut Decor {
128         &mut self.dotted_decor
129     }
130 
131     /// Returns the surrounding whitespace
132     #[deprecated(since = "0.21.1", note = "Replaced with `decor`")]
decor(&self) -> &Decor133     pub fn decor(&self) -> &Decor {
134         self.leaf_decor()
135     }
136 
137     /// Returns the surrounding whitespace for the line entry
leaf_decor(&self) -> &Decor138     pub fn leaf_decor(&self) -> &Decor {
139         &self.leaf_decor
140     }
141 
142     /// Returns the surrounding whitespace for between dots
dotted_decor(&self) -> &Decor143     pub fn dotted_decor(&self) -> &Decor {
144         &self.dotted_decor
145     }
146 
147     /// Returns the location within the original document
148     #[cfg(feature = "serde")]
span(&self) -> Option<std::ops::Range<usize>>149     pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
150         self.repr.as_ref().and_then(|r| r.span())
151     }
152 
despan(&mut self, input: &str)153     pub(crate) fn despan(&mut self, input: &str) {
154         self.leaf_decor.despan(input);
155         self.dotted_decor.despan(input);
156         if let Some(repr) = &mut self.repr {
157             repr.despan(input)
158         }
159     }
160 
161     /// Auto formats the key.
fmt(&mut self)162     pub fn fmt(&mut self) {
163         self.repr = None;
164         self.leaf_decor.clear();
165         self.dotted_decor.clear();
166     }
167 
168     #[cfg(feature = "parse")]
try_parse_simple(s: &str) -> Result<Key, crate::TomlError>169     fn try_parse_simple(s: &str) -> Result<Key, crate::TomlError> {
170         let mut key = crate::parser::parse_key(s)?;
171         key.despan(s);
172         Ok(key)
173     }
174 
175     #[cfg(feature = "parse")]
try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError>176     fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> {
177         let mut keys = crate::parser::parse_key_path(s)?;
178         for key in &mut keys {
179             key.despan(s);
180         }
181         Ok(keys)
182     }
183 }
184 
185 impl Clone for Key {
186     #[inline(never)]
clone(&self) -> Self187     fn clone(&self) -> Self {
188         Self {
189             key: self.key.clone(),
190             repr: self.repr.clone(),
191             leaf_decor: self.leaf_decor.clone(),
192             dotted_decor: self.dotted_decor.clone(),
193         }
194     }
195 }
196 
197 impl std::ops::Deref for Key {
198     type Target = str;
199 
deref(&self) -> &Self::Target200     fn deref(&self) -> &Self::Target {
201         self.get()
202     }
203 }
204 
205 impl std::hash::Hash for Key {
hash<H: std::hash::Hasher>(&self, state: &mut H)206     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
207         self.get().hash(state);
208     }
209 }
210 
211 impl Ord for Key {
cmp(&self, other: &Self) -> std::cmp::Ordering212     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
213         self.get().cmp(other.get())
214     }
215 }
216 
217 impl PartialOrd for Key {
partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering>218     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
219         Some(self.cmp(other))
220     }
221 }
222 
223 impl Eq for Key {}
224 
225 impl PartialEq for Key {
226     #[inline]
eq(&self, other: &Key) -> bool227     fn eq(&self, other: &Key) -> bool {
228         PartialEq::eq(self.get(), other.get())
229     }
230 }
231 
232 impl PartialEq<str> for Key {
233     #[inline]
eq(&self, other: &str) -> bool234     fn eq(&self, other: &str) -> bool {
235         PartialEq::eq(self.get(), other)
236     }
237 }
238 
239 impl<'s> PartialEq<&'s str> for Key {
240     #[inline]
eq(&self, other: &&str) -> bool241     fn eq(&self, other: &&str) -> bool {
242         PartialEq::eq(self.get(), *other)
243     }
244 }
245 
246 impl PartialEq<String> for Key {
247     #[inline]
eq(&self, other: &String) -> bool248     fn eq(&self, other: &String) -> bool {
249         PartialEq::eq(self.get(), other.as_str())
250     }
251 }
252 
253 #[cfg(feature = "display")]
254 impl std::fmt::Display for Key {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result255     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
256         crate::encode::encode_key(self, f, None)
257     }
258 }
259 
260 #[cfg(feature = "parse")]
261 impl FromStr for Key {
262     type Err = crate::TomlError;
263 
264     /// Tries to parse a key from a &str,
265     /// if fails, tries as basic quoted key (surrounds with "")
266     /// and then literal quoted key (surrounds with '')
from_str(s: &str) -> Result<Self, Self::Err>267     fn from_str(s: &str) -> Result<Self, Self::Err> {
268         Key::try_parse_simple(s)
269     }
270 }
271 
272 #[cfg(feature = "display")]
to_key_repr(key: &str) -> Repr273 fn to_key_repr(key: &str) -> Repr {
274     #[cfg(feature = "parse")]
275     {
276         if key
277             .as_bytes()
278             .iter()
279             .copied()
280             .all(crate::parser::key::is_unquoted_char)
281             && !key.is_empty()
282         {
283             Repr::new_unchecked(key)
284         } else {
285             crate::encode::to_string_repr(
286                 key,
287                 Some(crate::encode::StringStyle::OnelineSingle),
288                 Some(false),
289             )
290         }
291     }
292     #[cfg(not(feature = "parse"))]
293     {
294         crate::encode::to_string_repr(
295             key,
296             Some(crate::encode::StringStyle::OnelineSingle),
297             Some(false),
298         )
299     }
300 }
301 
302 impl<'b> From<&'b str> for Key {
from(s: &'b str) -> Self303     fn from(s: &'b str) -> Self {
304         Key::new(s)
305     }
306 }
307 
308 impl<'b> From<&'b String> for Key {
from(s: &'b String) -> Self309     fn from(s: &'b String) -> Self {
310         Key::new(s)
311     }
312 }
313 
314 impl From<String> for Key {
from(s: String) -> Self315     fn from(s: String) -> Self {
316         Key::new(s)
317     }
318 }
319 
320 impl From<InternalString> for Key {
from(s: InternalString) -> Self321     fn from(s: InternalString) -> Self {
322         Key::new(s)
323     }
324 }
325 
326 #[doc(hidden)]
327 impl From<Key> for InternalString {
from(key: Key) -> InternalString328     fn from(key: Key) -> InternalString {
329         key.key
330     }
331 }
332 
333 /// A mutable reference to a `Key`'s formatting
334 #[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
335 pub struct KeyMut<'k> {
336     key: &'k mut Key,
337 }
338 
339 impl<'k> KeyMut<'k> {
340     /// Returns the parsed key value.
get(&self) -> &str341     pub fn get(&self) -> &str {
342         self.key.get()
343     }
344 
345     /// Returns the raw representation, if available.
as_repr(&self) -> Option<&Repr>346     pub fn as_repr(&self) -> Option<&Repr> {
347         self.key.as_repr()
348     }
349 
350     /// Returns the default raw representation.
351     #[cfg(feature = "display")]
default_repr(&self) -> Repr352     pub fn default_repr(&self) -> Repr {
353         self.key.default_repr()
354     }
355 
356     /// Returns a raw representation.
357     #[cfg(feature = "display")]
display_repr(&self) -> Cow<str>358     pub fn display_repr(&self) -> Cow<str> {
359         self.key.display_repr()
360     }
361 
362     /// Returns the surrounding whitespace
363     #[deprecated(since = "0.21.1", note = "Replaced with `decor_mut`")]
decor_mut(&mut self) -> &mut Decor364     pub fn decor_mut(&mut self) -> &mut Decor {
365         #![allow(deprecated)]
366         self.key.decor_mut()
367     }
368 
369     /// Returns the surrounding whitespace for the line entry
leaf_decor_mut(&mut self) -> &mut Decor370     pub fn leaf_decor_mut(&mut self) -> &mut Decor {
371         self.key.leaf_decor_mut()
372     }
373 
374     /// Returns the surrounding whitespace for between dots
dotted_decor_mut(&mut self) -> &mut Decor375     pub fn dotted_decor_mut(&mut self) -> &mut Decor {
376         self.key.dotted_decor_mut()
377     }
378 
379     /// Returns the surrounding whitespace
380     #[deprecated(since = "0.21.1", note = "Replaced with `decor`")]
decor(&self) -> &Decor381     pub fn decor(&self) -> &Decor {
382         #![allow(deprecated)]
383         self.key.decor()
384     }
385 
386     /// Returns the surrounding whitespace for the line entry
leaf_decor(&self) -> &Decor387     pub fn leaf_decor(&self) -> &Decor {
388         self.key.leaf_decor()
389     }
390 
391     /// Returns the surrounding whitespace for between dots
dotted_decor(&self) -> &Decor392     pub fn dotted_decor(&self) -> &Decor {
393         self.key.dotted_decor()
394     }
395 
396     /// Auto formats the key.
fmt(&mut self)397     pub fn fmt(&mut self) {
398         self.key.fmt()
399     }
400 }
401 
402 impl<'k> std::ops::Deref for KeyMut<'k> {
403     type Target = str;
404 
deref(&self) -> &Self::Target405     fn deref(&self) -> &Self::Target {
406         self.get()
407     }
408 }
409 
410 impl<'s> PartialEq<str> for KeyMut<'s> {
411     #[inline]
eq(&self, other: &str) -> bool412     fn eq(&self, other: &str) -> bool {
413         PartialEq::eq(self.get(), other)
414     }
415 }
416 
417 impl<'s> PartialEq<&'s str> for KeyMut<'s> {
418     #[inline]
eq(&self, other: &&str) -> bool419     fn eq(&self, other: &&str) -> bool {
420         PartialEq::eq(self.get(), *other)
421     }
422 }
423 
424 impl<'s> PartialEq<String> for KeyMut<'s> {
425     #[inline]
eq(&self, other: &String) -> bool426     fn eq(&self, other: &String) -> bool {
427         PartialEq::eq(self.get(), other.as_str())
428     }
429 }
430 
431 #[cfg(feature = "display")]
432 impl<'k> std::fmt::Display for KeyMut<'k> {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result433     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
434         std::fmt::Display::fmt(&self.key, f)
435     }
436 }
437