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#[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 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 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 pub fn with_decor(mut self, decor: Decor) -> Self {
63 self.decor = decor;
64 self
65 }
66
67 pub fn as_mut(&mut self) -> KeyMut<'_> {
69 KeyMut { key: self }
70 }
71
72 pub fn get(&self) -> &str {
74 &self.key
75 }
76
77 pub(crate) fn get_internal(&self) -> &InternalString {
78 &self.key
79 }
80
81 pub fn as_repr(&self) -> Option<&Repr> {
83 self.repr.as_ref()
84 }
85
86 pub fn default_repr(&self) -> Repr {
88 to_key_repr(&self.key)
89 }
90
91 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 pub fn decor_mut(&mut self) -> &mut Decor {
103 &mut self.decor
104 }
105
106 pub fn decor(&self) -> &Decor {
108 &self.decor
109 }
110
111 #[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 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
139impl std::ops::Deref for Key {
140 type Target = str;
141
142 fn deref(&self) -> &Self::Target {
143 self.get()
144 }
145}
146
147impl std::hash::Hash for Key {
148 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
149 self.get().hash(state);
150 }
151}
152
153impl Ord for Key {
154 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
155 self.get().cmp(other.get())
156 }
157}
158
159impl PartialOrd for Key {
160 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
161 Some(self.cmp(other))
162 }
163}
164
165impl Eq for Key {}
166
167impl PartialEq for Key {
168 #[inline]
169 fn eq(&self, other: &Key) -> bool {
170 PartialEq::eq(self.get(), other.get())
171 }
172}
173
174impl PartialEq<str> for Key {
175 #[inline]
176 fn eq(&self, other: &str) -> bool {
177 PartialEq::eq(self.get(), other)
178 }
179}
180
181impl<'s> PartialEq<&'s str> for Key {
182 #[inline]
183 fn eq(&self, other: &&str) -> bool {
184 PartialEq::eq(self.get(), *other)
185 }
186}
187
188impl PartialEq<String> for Key {
189 #[inline]
190 fn eq(&self, other: &String) -> bool {
191 PartialEq::eq(self.get(), other.as_str())
192 }
193}
194
195impl 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
201impl FromStr for Key {
202 type Err = crate::TomlError;
203
204 fn from_str(s: &str) -> Result<Self, Self::Err> {
208 Key::try_parse_simple(s)
209 }
210}
211
212fn 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
220impl<'b> From<&'b str> for Key {
221 fn from(s: &'b str) -> Self {
222 Key::new(s)
223 }
224}
225
226impl<'b> From<&'b String> for Key {
227 fn from(s: &'b String) -> Self {
228 Key::new(s)
229 }
230}
231
232impl From<String> for Key {
233 fn from(s: String) -> Self {
234 Key::new(s)
235 }
236}
237
238impl From<InternalString> for Key {
239 fn from(s: InternalString) -> Self {
240 Key::new(s)
241 }
242}
243
244#[doc(hidden)]
245impl From<Key> for InternalString {
246 fn from(key: Key) -> InternalString {
247 key.key
248 }
249}
250
251#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
253pub struct KeyMut<'k> {
254 key: &'k mut Key,
255}
256
257impl<'k> KeyMut<'k> {
258 pub fn get(&self) -> &str {
260 self.key.get()
261 }
262
263 pub fn as_repr(&self) -> Option<&Repr> {
265 self.key.as_repr()
266 }
267
268 pub fn default_repr(&self) -> Repr {
270 self.key.default_repr()
271 }
272
273 pub fn display_repr(&self) -> Cow<str> {
275 self.key.display_repr()
276 }
277
278 pub fn decor_mut(&mut self) -> &mut Decor {
280 self.key.decor_mut()
281 }
282
283 pub fn decor(&self) -> &Decor {
285 self.key.decor()
286 }
287
288 pub fn fmt(&mut self) {
290 self.key.fmt()
291 }
292}
293
294impl<'k> std::ops::Deref for KeyMut<'k> {
295 type Target = str;
296
297 fn deref(&self) -> &Self::Target {
298 self.get()
299 }
300}
301
302impl<'s> PartialEq<str> for KeyMut<'s> {
303 #[inline]
304 fn eq(&self, other: &str) -> bool {
305 PartialEq::eq(self.get(), other)
306 }
307}
308
309impl<'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
316impl<'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
323impl<'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}