1use std::borrow::Cow;
2use std::str::FromStr;
3
4use crate::encode::{to_string_repr, StringStyle};
5use crate::parser;
6use crate::parser::key::is_unquoted_char;
7use crate::repr::{Decor, Repr};
8use 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)]
33pub struct Key {
34 key: InternalString,
35 pub(crate) repr: Option<Repr>,
36 pub(crate) decor: Decor,
37}
38
39impl 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
145impl std::ops::Deref for Key {
146 type Target = str;
147
148 fn deref(&self) -> &Self::Target {
149 self.get()
150 }
151}
152
153impl std::hash::Hash for Key {
154 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
155 self.get().hash(state);
156 }
157}
158
159impl Ord for Key {
160 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
161 self.get().cmp(other.get())
162 }
163}
164
165impl PartialOrd for Key {
166 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
167 Some(self.cmp(other))
168 }
169}
170
171impl Eq for Key {}
172
173impl PartialEq for Key {
174 #[inline]
175 fn eq(&self, other: &Key) -> bool {
176 PartialEq::eq(self.get(), other:other.get())
177 }
178}
179
180impl PartialEq<str> for Key {
181 #[inline]
182 fn eq(&self, other: &str) -> bool {
183 PartialEq::eq(self.get(), other)
184 }
185}
186
187impl<'s> PartialEq<&'s str> for Key {
188 #[inline]
189 fn eq(&self, other: &&str) -> bool {
190 PartialEq::eq(self.get(), *other)
191 }
192}
193
194impl 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
201impl 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
207impl 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
218fn 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
226impl<'b> From<&'b str> for Key {
227 fn from(s: &'b str) -> Self {
228 Key::new(key:s)
229 }
230}
231
232impl<'b> From<&'b String> for Key {
233 fn from(s: &'b String) -> Self {
234 Key::new(key:s)
235 }
236}
237
238impl From<String> for Key {
239 fn from(s: String) -> Self {
240 Key::new(key:s)
241 }
242}
243
244impl From<InternalString> for Key {
245 fn from(s: InternalString) -> Self {
246 Key::new(key:s)
247 }
248}
249
250#[doc(hidden)]
251impl 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)]
259pub struct KeyMut<'k> {
260 key: &'k mut Key,
261}
262
263impl<'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
300impl<'k> std::ops::Deref for KeyMut<'k> {
301 type Target = str;
302
303 fn deref(&self) -> &Self::Target {
304 self.get()
305 }
306}
307
308impl<'s> PartialEq<str> for KeyMut<'s> {
309 #[inline]
310 fn eq(&self, other: &str) -> bool {
311 PartialEq::eq(self.get(), other)
312 }
313}
314
315impl<'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
322impl<'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
329impl<'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