rune/workspace/
spanned_value.rs

1//! Definition of a TOML spanned value
2//!
3//! Copied from <https://github.com/est31/toml-spanned-value/tree/e925c52d22dc92c7147cf13ddbd43f78e02b8c32>.
4
5#![allow(unused)]
6
7use core::fmt;
8use core::mem::discriminant;
9use core::ops;
10use core::str::FromStr;
11
12use rust_alloc::string::{String, ToString};
13use rust_alloc::vec::Vec;
14
15use crate as rune;
16use crate::alloc::prelude::*;
17
18use serde::de;
19use serde::ser;
20
21pub(crate) use toml::value::{Datetime, DatetimeParseError};
22use toml::Spanned;
23
24pub(crate) use linked_hash_map::LinkedHashMap as Map;
25
26/// Type representing a value with a span
27pub(crate) type SpannedValue = Spanned<Value>;
28
29/// Representation of a TOML value.
30#[derive(PartialEq, Clone, Debug)]
31pub(crate) enum Value {
32    /// Represents a TOML string
33    String(String),
34    /// Represents a TOML integer
35    Integer(i64),
36    /// Represents a TOML float
37    Float(f64),
38    /// Represents a TOML boolean
39    Boolean(bool),
40    /// Represents a TOML datetime
41    Datetime(Datetime),
42    /// Represents a TOML array
43    Array(Array),
44    /// Represents a TOML table
45    Table(Table),
46}
47
48/// Type representing a TOML array, payload of the `Value::Array` variant
49pub(crate) type Array = Vec<SpannedValue>;
50
51/// Type representing a TOML table, payload of the `Value::Table` variant.
52/// By default it is backed by a BTreeMap, enable the `preserve_order` feature
53/// to use a LinkedHashMap instead.
54pub(crate) type Table = Map<Spanned<String>, SpannedValue>;
55
56impl Value {
57    /* /// Interpret a `toml::Value` as an instance of type `T`.
58    ///
59    /// This conversion can fail if the structure of the `Value` does not match the
60    /// structure expected by `T`, for example if `T` is a struct type but the
61    /// `Value` contains something other than a TOML table. It can also fail if the
62    /// structure is correct but `T`'s implementation of `Deserialize` decides that
63    /// something is wrong with the data, for example required struct fields are
64    /// missing from the TOML map or some number is too big to fit in the expected
65    /// primitive type.
66    pub(crate) fn try_into<'de, T>(self) -> Result<T, crate::de::Error>
67    where
68        T: de::Deserialize<'de>,
69    {
70        de::Deserialize::deserialize(self)
71    }*/
72
73    /// Index into a TOML array or map. A string index can be used to access a
74    /// value in a map, and a usize index can be used to access an element of an
75    /// array.
76    ///
77    /// Returns `None` if the type of `self` does not match the type of the
78    /// index, for example if the index is a string and `self` is an array or a
79    /// number. Also returns `None` if the given key does not exist in the map
80    /// or the given index is not within the bounds of the array.
81    pub(crate) fn get<I: Index>(&self, index: I) -> Option<&SpannedValue> {
82        index.index(self)
83    }
84
85    /// Mutably index into a TOML array or map. A string index can be used to
86    /// access a value in a map, and a usize index can be used to access an
87    /// element of an array.
88    ///
89    /// Returns `None` if the type of `self` does not match the type of the
90    /// index, for example if the index is a string and `self` is an array or a
91    /// number. Also returns `None` if the given key does not exist in the map
92    /// or the given index is not within the bounds of the array.
93    pub(crate) fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut SpannedValue> {
94        index.index_mut(self)
95    }
96
97    /// Extracts the integer value if it is an integer.
98    pub(crate) fn as_integer(&self) -> Option<i64> {
99        match *self {
100            Value::Integer(i) => Some(i),
101            _ => None,
102        }
103    }
104
105    /// Tests whether this value is an integer.
106    pub(crate) fn is_integer(&self) -> bool {
107        self.as_integer().is_some()
108    }
109
110    /// Extracts the float value if it is a float.
111    pub(crate) fn as_float(&self) -> Option<f64> {
112        match *self {
113            Value::Float(f) => Some(f),
114            _ => None,
115        }
116    }
117
118    /// Tests whether this value is a float.
119    pub(crate) fn is_float(&self) -> bool {
120        self.as_float().is_some()
121    }
122
123    /// Extracts the boolean value if it is a boolean.
124    pub(crate) fn as_bool(&self) -> Option<bool> {
125        match *self {
126            Value::Boolean(b) => Some(b),
127            _ => None,
128        }
129    }
130
131    /// Tests whether this value is a boolean.
132    pub(crate) fn is_bool(&self) -> bool {
133        self.as_bool().is_some()
134    }
135
136    /// Extracts the string of this value if it is a string.
137    pub(crate) fn as_str(&self) -> Option<&str> {
138        match *self {
139            Value::String(ref s) => Some(&**s),
140            _ => None,
141        }
142    }
143
144    /// Tests if this value is a string.
145    pub(crate) fn is_str(&self) -> bool {
146        self.as_str().is_some()
147    }
148
149    /// Extracts the datetime value if it is a datetime.
150    ///
151    /// Note that a parsed TOML value will only contain ISO 8601 dates. An
152    /// example date is:
153    ///
154    /// ```notrust
155    /// 1979-05-27T07:32:00Z
156    /// ```
157    pub(crate) fn as_datetime(&self) -> Option<&Datetime> {
158        match *self {
159            Value::Datetime(ref s) => Some(s),
160            _ => None,
161        }
162    }
163
164    /// Tests whether this value is a datetime.
165    pub(crate) fn is_datetime(&self) -> bool {
166        self.as_datetime().is_some()
167    }
168
169    /// Extracts the array value if it is an array.
170    pub(crate) fn as_array(&self) -> Option<&Vec<SpannedValue>> {
171        match *self {
172            Value::Array(ref s) => Some(s),
173            _ => None,
174        }
175    }
176
177    /// Extracts the array value if it is an array.
178    pub(crate) fn as_array_mut(&mut self) -> Option<&mut Vec<SpannedValue>> {
179        match *self {
180            Value::Array(ref mut s) => Some(s),
181            _ => None,
182        }
183    }
184
185    /// Tests whether this value is an array.
186    pub(crate) fn is_array(&self) -> bool {
187        self.as_array().is_some()
188    }
189
190    /// Extracts the table value if it is a table.
191    pub(crate) fn as_table(&self) -> Option<&Table> {
192        match *self {
193            Value::Table(ref s) => Some(s),
194            _ => None,
195        }
196    }
197
198    /// Extracts the table value if it is a table.
199    pub(crate) fn as_table_mut(&mut self) -> Option<&mut Table> {
200        match *self {
201            Value::Table(ref mut s) => Some(s),
202            _ => None,
203        }
204    }
205
206    /// Tests whether this value is a table.
207    pub(crate) fn is_table(&self) -> bool {
208        self.as_table().is_some()
209    }
210
211    /// Tests whether this and another value have the same type.
212    pub(crate) fn same_type(&self, other: &Value) -> bool {
213        discriminant(self) == discriminant(other)
214    }
215
216    /// Returns a human-readable representation of the type of this value.
217    pub(crate) fn type_str(&self) -> &'static str {
218        match *self {
219            Value::String(..) => "string",
220            Value::Integer(..) => "integer",
221            Value::Float(..) => "float",
222            Value::Boolean(..) => "boolean",
223            Value::Datetime(..) => "datetime",
224            Value::Array(..) => "array",
225            Value::Table(..) => "table",
226        }
227    }
228}
229
230impl<I> ops::Index<I> for Value
231where
232    I: Index,
233{
234    type Output = SpannedValue;
235
236    fn index(&self, index: I) -> &SpannedValue {
237        self.get(index).expect("index not found")
238    }
239}
240
241impl<I> ops::IndexMut<I> for Value
242where
243    I: Index,
244{
245    fn index_mut(&mut self, index: I) -> &mut SpannedValue {
246        self.get_mut(index).expect("index not found")
247    }
248}
249
250impl From<&str> for Value {
251    #[inline]
252    fn from(string: &str) -> Value {
253        Value::String(string.to_string())
254    }
255}
256
257impl<V> From<Vec<V>> for Value
258where
259    V: Into<SpannedValue>,
260{
261    fn from(val: Vec<V>) -> Value {
262        Value::Array(val.into_iter().map(|v| v.into()).collect())
263    }
264}
265
266macro_rules! impl_into_value {
267    ($variant:ident : $T:ty) => {
268        impl From<$T> for Value {
269            #[inline]
270            fn from(val: $T) -> Value {
271                Value::$variant(val.into())
272            }
273        }
274    };
275}
276
277impl_into_value!(String: String);
278impl_into_value!(Integer: i64);
279impl_into_value!(Integer: i32);
280impl_into_value!(Integer: i8);
281impl_into_value!(Integer: u8);
282impl_into_value!(Integer: u32);
283impl_into_value!(Float: f64);
284impl_into_value!(Float: f32);
285impl_into_value!(Boolean: bool);
286impl_into_value!(Datetime: Datetime);
287impl_into_value!(Table: Table);
288
289/// Types that can be used to index a `toml::Value`
290///
291/// Currently this is implemented for `usize` to index arrays and `str` to index
292/// tables.
293///
294/// This trait is sealed and not intended for implementation outside of the
295/// `toml` crate.
296pub(crate) trait Index: Sealed {
297    #[doc(hidden)]
298    fn index<'a>(&self, val: &'a Value) -> Option<&'a SpannedValue>;
299    #[doc(hidden)]
300    fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut SpannedValue>;
301}
302
303/// An implementation detail that should not be implemented, this will change in
304/// the future and break code otherwise.
305#[doc(hidden)]
306pub(crate) trait Sealed {}
307impl Sealed for usize {}
308impl Sealed for str {}
309impl Sealed for String {}
310impl<T: ?Sized + Sealed> Sealed for &T {}
311
312impl Index for usize {
313    fn index<'a>(&self, val: &'a Value) -> Option<&'a SpannedValue> {
314        match *val {
315            Value::Array(ref a) => a.get(*self),
316            _ => None,
317        }
318    }
319
320    fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut SpannedValue> {
321        match *val {
322            Value::Array(ref mut a) => a.get_mut(*self),
323            _ => None,
324        }
325    }
326}
327
328impl Index for str {
329    fn index<'a>(&self, val: &'a Value) -> Option<&'a SpannedValue> {
330        match *val {
331            Value::Table(ref a) => a.get(self),
332            _ => None,
333        }
334    }
335
336    fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut SpannedValue> {
337        match *val {
338            Value::Table(ref mut a) => a.get_mut(self),
339            _ => None,
340        }
341    }
342}
343
344impl Index for String {
345    fn index<'a>(&self, val: &'a Value) -> Option<&'a SpannedValue> {
346        self[..].index(val)
347    }
348
349    fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut SpannedValue> {
350        self[..].index_mut(val)
351    }
352}
353
354impl<T> Index for &T
355where
356    T: ?Sized + Index,
357{
358    fn index<'a>(&self, val: &'a Value) -> Option<&'a SpannedValue> {
359        (**self).index(val)
360    }
361
362    fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut SpannedValue> {
363        (**self).index_mut(val)
364    }
365}
366
367impl fmt::Display for Value {
368    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369        toml::ser::to_string(self)
370            .expect("Unable to represent value as string")
371            .fmt(f)
372    }
373}
374
375impl FromStr for Value {
376    type Err = toml::de::Error;
377    fn from_str(s: &str) -> Result<Value, Self::Err> {
378        toml::from_str(s)
379    }
380}
381
382impl ser::Serialize for Value {
383    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
384    where
385        S: ser::Serializer,
386    {
387        use serde::ser::SerializeMap;
388
389        match *self {
390            Value::String(ref s) => serializer.serialize_str(s),
391            Value::Integer(i) => serializer.serialize_i64(i),
392            Value::Float(f) => serializer.serialize_f64(f),
393            Value::Boolean(b) => serializer.serialize_bool(b),
394            Value::Datetime(ref s) => s.serialize(serializer),
395            Value::Array(ref a) => a.serialize(serializer),
396            Value::Table(ref t) => {
397                let mut map = serializer.serialize_map(Some(t.len()))?;
398                // Be sure to visit non-tables first (and also non
399                // array-of-tables) as all keys must be emitted first.
400                for (k, v) in t {
401                    if !v.get_ref().is_table() && !v.get_ref().is_array()
402                        || (v
403                            .get_ref()
404                            .as_array()
405                            .map(|a| !a.iter().any(|v| v.get_ref().is_table()))
406                            .unwrap_or(false))
407                    {
408                        map.serialize_entry(k, v)?;
409                    }
410                }
411                for (k, v) in t {
412                    if v.get_ref()
413                        .as_array()
414                        .map(|a| a.iter().any(|v| v.get_ref().is_table()))
415                        .unwrap_or(false)
416                    {
417                        map.serialize_entry(k, v)?;
418                    }
419                }
420                for (k, v) in t {
421                    if v.get_ref().is_table() {
422                        map.serialize_entry(k, v)?;
423                    }
424                }
425                map.end()
426            }
427        }
428    }
429}
430
431impl<'de> de::Deserialize<'de> for Value {
432    fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
433    where
434        D: de::Deserializer<'de>,
435    {
436        struct MutableValueVisitor;
437
438        impl<'de> de::Visitor<'de> for MutableValueVisitor {
439            type Value = Value;
440
441            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
442                formatter.write_str("any valid TOML value")
443            }
444
445            fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
446                Ok(Value::Boolean(value))
447            }
448
449            fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
450                Ok(Value::Integer(value))
451            }
452
453            fn visit_u64<E>(self, value: u64) -> Result<Value, E>
454            where
455                E: de::Error,
456            {
457                if let Ok(value) = i64::try_from(value) {
458                    return Ok(Value::Integer(value));
459                }
460
461                Err(de::Error::custom("u64 value was too large"))
462            }
463
464            fn visit_u32<E>(self, value: u32) -> Result<Value, E> {
465                Ok(Value::Integer(value.into()))
466            }
467
468            fn visit_i32<E>(self, value: i32) -> Result<Value, E> {
469                Ok(Value::Integer(value.into()))
470            }
471
472            fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
473                Ok(Value::Float(value))
474            }
475
476            fn visit_str<E>(self, value: &str) -> Result<Value, E>
477            where
478                E: de::Error,
479            {
480                Ok(Value::String(value.to_string()))
481            }
482
483            fn visit_string<E>(self, value: String) -> Result<Value, E>
484            where
485                E: de::Error,
486            {
487                Ok(Value::String(value))
488            }
489
490            fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
491            where
492                D: de::Deserializer<'de>,
493            {
494                de::Deserialize::deserialize(deserializer)
495            }
496
497            fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
498            where
499                V: de::SeqAccess<'de>,
500            {
501                let mut vec = Vec::new();
502                while let Some(elem) = visitor.next_element()? {
503                    vec.push(elem);
504                }
505                Ok(Value::Array(vec))
506            }
507
508            fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
509            where
510                V: de::MapAccess<'de>,
511            {
512                let key = visitor.next_key_seed(DatetimeOrTable)?;
513                let key = match key {
514                    Some(Some(key)) => key,
515                    Some(None) => {
516                        let date: DatetimeFromString = visitor.next_value()?;
517                        return Ok(Value::Datetime(date.value));
518                    }
519                    None => return Ok(Value::Table(Map::new())),
520                };
521                let mut map = Map::new();
522                map.insert(key, visitor.next_value()?);
523                while let Some(key) = visitor.next_key()? {
524                    if map.contains_key(&key) {
525                        let key: Spanned<String> = key;
526                        let msg = format!("duplicate key: `{}`", key.get_ref());
527                        return Err(de::Error::custom(msg));
528                    }
529                    map.insert(key, visitor.next_value()?);
530                }
531                Ok(Value::Table(map))
532            }
533        }
534
535        deserializer.deserialize_any(MutableValueVisitor)
536    }
537}
538
539struct DatetimeFromString {
540    pub(crate) value: Datetime,
541}
542
543impl<'de> de::Deserialize<'de> for DatetimeFromString {
544    fn deserialize<D>(deserializer: D) -> Result<DatetimeFromString, D::Error>
545    where
546        D: de::Deserializer<'de>,
547    {
548        struct Visitor;
549
550        impl de::Visitor<'_> for Visitor {
551            type Value = DatetimeFromString;
552
553            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
554                formatter.write_str("string containing a datetime")
555            }
556
557            fn visit_str<E>(self, s: &str) -> Result<DatetimeFromString, E>
558            where
559                E: de::Error,
560            {
561                match s.parse() {
562                    Ok(date) => Ok(DatetimeFromString { value: date }),
563                    Err(e) => Err(de::Error::custom(e)),
564                }
565            }
566        }
567
568        deserializer.deserialize_str(Visitor)
569    }
570}
571
572#[derive(Debug)]
573struct OptError<E: de::Error>(Option<E>);
574
575impl<E: de::Error> core::error::Error for OptError<E> {}
576
577impl<E: de::Error> core::fmt::Display for OptError<E> {
578    fn fmt(&self, _fmt: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
579        // The error is never meant to be displayed.
580        // Our code is expected to unwrap the error before
581        // it is propagated to places that may display it.
582        unreachable!()
583    }
584}
585
586impl<E: de::Error> de::Error for OptError<E> {
587    fn custom<T: core::fmt::Display>(msg: T) -> Self {
588        Self(Some(<E as de::Error>::custom(msg)))
589    }
590}
591
592struct LayerDeserializer<'de, D: de::Deserializer<'de>>(D, std::marker::PhantomData<&'de ()>);
593
594impl<'de, D: de::Deserializer<'de>> de::Deserializer<'de> for LayerDeserializer<'de, D> {
595    type Error = OptError<D::Error>;
596    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
597    where
598        V: de::Visitor<'de>,
599    {
600        self.0
601            .deserialize_any(visitor)
602            .map_err(|e| OptError(Some(e)))
603    }
604    fn deserialize_struct<V>(
605        self,
606        name: &'static str,
607        fields: &'static [&'static str],
608        visitor: V,
609    ) -> Result<V::Value, Self::Error>
610    where
611        V: de::Visitor<'de>,
612    {
613        let wrapped_visitor = DatetimeOrTableWrapper(visitor);
614        match self.0.deserialize_struct(name, fields, wrapped_visitor) {
615            Ok(Some(v)) => Ok(v),
616            Ok(None) => Err(OptError(None)),
617            Err(v) => Err(OptError(Some(v))),
618        }
619    }
620    serde::forward_to_deserialize_any! {
621        bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
622        bytes byte_buf option unit unit_struct newtype_struct seq tuple
623        tuple_struct map enum identifier ignored_any
624    }
625}
626
627struct DatetimeOrTable;
628
629impl<'de> de::DeserializeSeed<'de> for DatetimeOrTable {
630    type Value = Option<Spanned<String>>;
631
632    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
633    where
634        D: de::Deserializer<'de>,
635    {
636        let deserializer = LayerDeserializer(deserializer, std::marker::PhantomData);
637        let res = <Spanned<String> as de::Deserialize<'_>>::deserialize(deserializer);
638        match res {
639            Ok(v) => Ok(Some(v)),
640            Err(OptError(None)) => Ok(None),
641            Err(OptError(Some(e))) => Err(e),
642        }
643    }
644}
645
646struct DatetimeOrTableWrapper<V>(V);
647
648impl<'de, V: de::Visitor<'de>> de::Visitor<'de> for DatetimeOrTableWrapper<V> {
649    type Value = Option<V::Value>;
650
651    fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
652        formatter.write_str("a string key")
653    }
654
655    fn visit_map<W>(self, visitor: W) -> Result<Self::Value, W::Error>
656    where
657        W: de::MapAccess<'de>,
658    {
659        let key = self.0.visit_map(visitor)?;
660        Ok(Some(key))
661    }
662
663    fn visit_str<E>(self, _s: &str) -> Result<Self::Value, E>
664    where
665        E: de::Error,
666    {
667        //assert_eq!(s, toml::datetime::FIELD);
668        Ok(None)
669    }
670
671    fn visit_string<E>(self, _s: rust_alloc::string::String) -> Result<Self::Value, E>
672    where
673        E: de::Error,
674    {
675        //assert_eq!(s, toml::datetime::FIELD);
676        Ok(None)
677    }
678}