]> git.proxmox.com Git - rustc.git/blob - vendor/toml_edit/src/key.rs
New upstream version 1.70.0+dfsg2
[rustc.git] / vendor / toml_edit / src / key.rs
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 parser::parse_key(s)
132 }
133
134 fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> {
135 parser::parse_key_path(s)
136 }
137 }
138
139 impl std::ops::Deref for Key {
140 type Target = str;
141
142 fn deref(&self) -> &Self::Target {
143 self.get()
144 }
145 }
146
147 impl std::hash::Hash for Key {
148 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
149 self.get().hash(state);
150 }
151 }
152
153 impl Ord for Key {
154 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
155 self.get().cmp(other.get())
156 }
157 }
158
159 impl PartialOrd for Key {
160 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
161 Some(self.cmp(other))
162 }
163 }
164
165 impl Eq for Key {}
166
167 impl PartialEq for Key {
168 #[inline]
169 fn eq(&self, other: &Key) -> bool {
170 PartialEq::eq(self.get(), other.get())
171 }
172 }
173
174 impl PartialEq<str> for Key {
175 #[inline]
176 fn eq(&self, other: &str) -> bool {
177 PartialEq::eq(self.get(), other)
178 }
179 }
180
181 impl<'s> PartialEq<&'s str> for Key {
182 #[inline]
183 fn eq(&self, other: &&str) -> bool {
184 PartialEq::eq(self.get(), *other)
185 }
186 }
187
188 impl PartialEq<String> for Key {
189 #[inline]
190 fn eq(&self, other: &String) -> bool {
191 PartialEq::eq(self.get(), other.as_str())
192 }
193 }
194
195 impl std::fmt::Display for Key {
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 crate::encode::Encode::encode(self, f, None, ("", ""))
198 }
199 }
200
201 impl FromStr for Key {
202 type Err = crate::TomlError;
203
204 /// Tries to parse a key from a &str,
205 /// if fails, tries as basic quoted key (surrounds with "")
206 /// and then literal quoted key (surrounds with '')
207 fn from_str(s: &str) -> Result<Self, Self::Err> {
208 Key::try_parse_simple(s)
209 }
210 }
211
212 fn to_key_repr(key: &str) -> Repr {
213 if key.as_bytes().iter().copied().all(is_unquoted_char) && !key.is_empty() {
214 Repr::new_unchecked(key)
215 } else {
216 to_string_repr(key, Some(StringStyle::OnelineSingle), Some(false))
217 }
218 }
219
220 impl<'b> From<&'b str> for Key {
221 fn from(s: &'b str) -> Self {
222 Key::new(s)
223 }
224 }
225
226 impl<'b> From<&'b String> for Key {
227 fn from(s: &'b String) -> Self {
228 Key::new(s)
229 }
230 }
231
232 impl From<String> for Key {
233 fn from(s: String) -> Self {
234 Key::new(s)
235 }
236 }
237
238 impl From<InternalString> for Key {
239 fn from(s: InternalString) -> Self {
240 Key::new(s)
241 }
242 }
243
244 #[doc(hidden)]
245 impl From<Key> for InternalString {
246 fn from(key: Key) -> InternalString {
247 key.key
248 }
249 }
250
251 /// A mutable reference to a `Key`
252 #[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
253 pub struct KeyMut<'k> {
254 key: &'k mut Key,
255 }
256
257 impl<'k> KeyMut<'k> {
258 /// Returns the parsed key value.
259 pub fn get(&self) -> &str {
260 self.key.get()
261 }
262
263 /// Returns the raw representation, if available.
264 pub fn as_repr(&self) -> Option<&Repr> {
265 self.key.as_repr()
266 }
267
268 /// Returns the default raw representation.
269 pub fn default_repr(&self) -> Repr {
270 self.key.default_repr()
271 }
272
273 /// Returns a raw representation.
274 pub fn display_repr(&self) -> Cow<str> {
275 self.key.display_repr()
276 }
277
278 /// Returns the surrounding whitespace
279 pub fn decor_mut(&mut self) -> &mut Decor {
280 self.key.decor_mut()
281 }
282
283 /// Returns the surrounding whitespace
284 pub fn decor(&self) -> &Decor {
285 self.key.decor()
286 }
287
288 /// Auto formats the key.
289 pub fn fmt(&mut self) {
290 self.key.fmt()
291 }
292 }
293
294 impl<'k> std::ops::Deref for KeyMut<'k> {
295 type Target = str;
296
297 fn deref(&self) -> &Self::Target {
298 self.get()
299 }
300 }
301
302 impl<'s> PartialEq<str> for KeyMut<'s> {
303 #[inline]
304 fn eq(&self, other: &str) -> bool {
305 PartialEq::eq(self.get(), other)
306 }
307 }
308
309 impl<'s> PartialEq<&'s str> for KeyMut<'s> {
310 #[inline]
311 fn eq(&self, other: &&str) -> bool {
312 PartialEq::eq(self.get(), *other)
313 }
314 }
315
316 impl<'s> PartialEq<String> for KeyMut<'s> {
317 #[inline]
318 fn eq(&self, other: &String) -> bool {
319 PartialEq::eq(self.get(), other.as_str())
320 }
321 }
322
323 impl<'k> std::fmt::Display for KeyMut<'k> {
324 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325 std::fmt::Display::fmt(&self.key, f)
326 }
327 }