toml/de/parser/
devalue.rs1use alloc::borrow::Cow;
4use core::mem::discriminant;
5use core::ops;
6
7use serde_spanned::Spanned;
8use toml_datetime::Datetime;
9
10use crate::alloc_prelude::*;
11use crate::de::DeArray;
12use crate::de::DeTable;
13
14pub type DeString<'i> = Cow<'i, str>;
16
17#[derive(Clone, Debug)]
19pub struct DeInteger<'i> {
20 pub(crate) inner: DeString<'i>,
21 pub(crate) radix: u32,
22}
23
24impl DeInteger<'_> {
25 pub(crate) fn to_u64(&self) -> Option<u64> {
26 u64::from_str_radix(self.inner.as_ref(), self.radix).ok()
27 }
28 pub(crate) fn to_i64(&self) -> Option<i64> {
29 i64::from_str_radix(self.inner.as_ref(), self.radix).ok()
30 }
31 pub(crate) fn to_u128(&self) -> Option<u128> {
32 u128::from_str_radix(self.inner.as_ref(), self.radix).ok()
33 }
34 pub(crate) fn to_i128(&self) -> Option<i128> {
35 i128::from_str_radix(self.inner.as_ref(), self.radix).ok()
36 }
37
38 pub fn as_str(&self) -> &str {
44 self.inner.as_ref()
45 }
46
47 pub fn radix(&self) -> u32 {
49 self.radix
50 }
51
52 pub fn make_owned(&mut self) {
54 let owned = core::mem::take(&mut self.inner);
55 self.inner = Cow::Owned(owned.into_owned());
56 }
57}
58
59impl Default for DeInteger<'_> {
60 fn default() -> Self {
61 Self {
62 inner: DeString::Borrowed("0"),
63 radix: 10,
64 }
65 }
66}
67
68impl core::fmt::Display for DeInteger<'_> {
69 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
70 match self.radix {
71 2 => "0b".fmt(formatter)?,
72 8 => "0o".fmt(formatter)?,
73 10 => {}
74 16 => "0x".fmt(formatter)?,
75 _ => {
76 unreachable!(
77 "we should only ever have 2, 8, 10, and 16 radix, not {}",
78 self.radix
79 )
80 }
81 }
82 self.as_str().fmt(formatter)?;
83 Ok(())
84 }
85}
86
87#[derive(Clone, Debug)]
89pub struct DeFloat<'i> {
90 pub(crate) inner: DeString<'i>,
91}
92
93impl DeFloat<'_> {
94 pub(crate) fn to_f64(&self) -> Option<f64> {
95 let f: f64 = self.inner.as_ref().parse().ok()?;
96 if f.is_infinite() && !self.as_str().contains("inf") {
97 None
98 } else {
99 Some(f)
100 }
101 }
102
103 pub fn as_str(&self) -> &str {
105 self.inner.as_ref()
106 }
107
108 pub fn make_owned(&mut self) {
110 let owned = core::mem::take(&mut self.inner);
111 self.inner = Cow::Owned(owned.into_owned());
112 }
113}
114
115impl Default for DeFloat<'_> {
116 fn default() -> Self {
117 Self {
118 inner: DeString::Borrowed("0.0"),
119 }
120 }
121}
122
123impl core::fmt::Display for DeFloat<'_> {
124 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
125 self.as_str().fmt(formatter)?;
126 Ok(())
127 }
128}
129
130#[derive(Clone, Debug)]
132pub enum DeValue<'i> {
133 String(DeString<'i>),
135 Integer(DeInteger<'i>),
137 Float(DeFloat<'i>),
139 Boolean(bool),
141 Datetime(Datetime),
143 Array(DeArray<'i>),
145 Table(DeTable<'i>),
147}
148
149impl<'i> DeValue<'i> {
150 pub fn parse(input: &'i str) -> Result<Spanned<Self>, crate::de::Error> {
152 let source = toml_parser::Source::new(input);
153 let mut errors = crate::de::error::TomlSink::<Option<_>>::new(source);
154 let value = crate::de::parser::parse_value(source, &mut errors);
155 if let Some(err) = errors.into_inner() {
156 Err(err)
157 } else {
158 Ok(value)
159 }
160 }
161
162 pub fn parse_recoverable(input: &'i str) -> (Spanned<Self>, Vec<crate::de::Error>) {
164 let source = toml_parser::Source::new(input);
165 let mut errors = crate::de::error::TomlSink::<Vec<_>>::new(source);
166 let value = crate::de::parser::parse_value(source, &mut errors);
167 (value, errors.into_inner())
168 }
169
170 pub fn make_owned(&mut self) {
172 match self {
173 DeValue::String(v) => {
174 let owned = core::mem::take(v);
175 *v = Cow::Owned(owned.into_owned());
176 }
177 DeValue::Integer(v) => {
178 v.make_owned();
179 }
180 DeValue::Float(v) => {
181 v.make_owned();
182 }
183 DeValue::Boolean(..) | DeValue::Datetime(..) => {}
184 DeValue::Array(v) => {
185 for e in v.iter_mut() {
186 e.get_mut().make_owned();
187 }
188 }
189 DeValue::Table(v) => v.make_owned(),
190 }
191 }
192
193 pub fn get<I: Index>(&self, index: I) -> Option<&Spanned<Self>> {
202 index.index(self)
203 }
204
205 pub fn as_integer(&self) -> Option<&DeInteger<'i>> {
207 match self {
208 DeValue::Integer(i) => Some(i),
209 _ => None,
210 }
211 }
212
213 pub fn is_integer(&self) -> bool {
215 self.as_integer().is_some()
216 }
217
218 pub fn as_float(&self) -> Option<&DeFloat<'i>> {
220 match self {
221 DeValue::Float(f) => Some(f),
222 _ => None,
223 }
224 }
225
226 pub fn is_float(&self) -> bool {
228 self.as_float().is_some()
229 }
230
231 pub fn as_bool(&self) -> Option<bool> {
233 match *self {
234 DeValue::Boolean(b) => Some(b),
235 _ => None,
236 }
237 }
238
239 pub fn is_bool(&self) -> bool {
241 self.as_bool().is_some()
242 }
243
244 pub fn as_str(&self) -> Option<&str> {
246 match *self {
247 DeValue::String(ref s) => Some(&**s),
248 _ => None,
249 }
250 }
251
252 pub fn is_str(&self) -> bool {
254 self.as_str().is_some()
255 }
256
257 pub fn as_datetime(&self) -> Option<&Datetime> {
266 match *self {
267 DeValue::Datetime(ref s) => Some(s),
268 _ => None,
269 }
270 }
271
272 pub fn is_datetime(&self) -> bool {
274 self.as_datetime().is_some()
275 }
276
277 pub fn as_array(&self) -> Option<&DeArray<'i>> {
279 match *self {
280 DeValue::Array(ref s) => Some(s),
281 _ => None,
282 }
283 }
284
285 pub(crate) fn as_array_mut(&mut self) -> Option<&mut DeArray<'i>> {
286 match self {
287 DeValue::Array(s) => Some(s),
288 _ => None,
289 }
290 }
291
292 pub fn is_array(&self) -> bool {
294 self.as_array().is_some()
295 }
296
297 pub fn as_table(&self) -> Option<&DeTable<'i>> {
299 match *self {
300 DeValue::Table(ref s) => Some(s),
301 _ => None,
302 }
303 }
304
305 pub(crate) fn as_table_mut(&mut self) -> Option<&mut DeTable<'i>> {
306 match self {
307 DeValue::Table(s) => Some(s),
308 _ => None,
309 }
310 }
311
312 pub fn is_table(&self) -> bool {
314 self.as_table().is_some()
315 }
316
317 pub fn same_type(&self, other: &DeValue<'_>) -> bool {
319 discriminant(self) == discriminant(other)
320 }
321
322 pub fn type_str(&self) -> &'static str {
324 match *self {
325 DeValue::String(..) => "string",
326 DeValue::Integer(..) => "integer",
327 DeValue::Float(..) => "float",
328 DeValue::Boolean(..) => "boolean",
329 DeValue::Datetime(..) => "datetime",
330 DeValue::Array(..) => "array",
331 DeValue::Table(..) => "table",
332 }
333 }
334}
335
336impl<I> ops::Index<I> for DeValue<'_>
337where
338 I: Index,
339{
340 type Output = Spanned<Self>;
341
342 fn index(&self, index: I) -> &Spanned<Self> {
343 self.get(index).expect("index not found")
344 }
345}
346
347pub trait Index: Sealed {
355 #[doc(hidden)]
356 fn index<'r, 'i>(&self, val: &'r DeValue<'i>) -> Option<&'r Spanned<DeValue<'i>>>;
357}
358
359#[doc(hidden)]
362pub trait Sealed {}
363impl Sealed for usize {}
364impl Sealed for str {}
365impl Sealed for String {}
366impl<T: Sealed + ?Sized> Sealed for &T {}
367
368impl Index for usize {
369 fn index<'r, 'i>(&self, val: &'r DeValue<'i>) -> Option<&'r Spanned<DeValue<'i>>> {
370 match *val {
371 DeValue::Array(ref a) => a.get(*self),
372 _ => None,
373 }
374 }
375}
376
377impl Index for str {
378 fn index<'r, 'i>(&self, val: &'r DeValue<'i>) -> Option<&'r Spanned<DeValue<'i>>> {
379 match *val {
380 DeValue::Table(ref a) => a.get(self),
381 _ => None,
382 }
383 }
384}
385
386impl Index for String {
387 fn index<'r, 'i>(&self, val: &'r DeValue<'i>) -> Option<&'r Spanned<DeValue<'i>>> {
388 self[..].index(val)
389 }
390}
391
392impl<T> Index for &T
393where
394 T: Index + ?Sized,
395{
396 fn index<'r, 'i>(&self, val: &'r DeValue<'i>) -> Option<&'r Spanned<DeValue<'i>>> {
397 (**self).index(val)
398 }
399}