serde_spanned/
spanned.rs

1use std::cmp::Ordering;
2use std::hash::{Hash, Hasher};
3
4// Currently serde itself doesn't have a spanned type, so we map our `Spanned`
5// to a special value in the serde data model. Namely one with these special
6// fields/struct names.
7//
8// In general, supported deserializers should catch this and not literally emit
9// these strings but rather emit `Spanned` as they're intended.
10#[doc(hidden)]
11#[cfg(feature = "serde")]
12pub const NAME: &str = "$__serde_spanned_private_Spanned";
13#[doc(hidden)]
14#[cfg(feature = "serde")]
15pub const START_FIELD: &str = "$__serde_spanned_private_start";
16#[doc(hidden)]
17#[cfg(feature = "serde")]
18pub const END_FIELD: &str = "$__serde_spanned_private_end";
19#[doc(hidden)]
20#[cfg(feature = "serde")]
21pub const VALUE_FIELD: &str = "$__serde_spanned_private_value";
22#[doc(hidden)]
23#[cfg(feature = "serde")]
24pub fn is_spanned(name: &'static str, fields: &'static [&'static str]) -> bool {
25    name == NAME && fields == [START_FIELD, END_FIELD, VALUE_FIELD]
26}
27
28/// A spanned value, indicating the range at which it is defined in the source.
29#[derive(Clone, Debug)]
30pub struct Spanned<T> {
31    /// Byte range
32    span: std::ops::Range<usize>,
33    /// The spanned value.
34    value: T,
35}
36
37impl<T> Spanned<T> {
38    /// Create a spanned value encompassing the given byte range.
39    ///
40    /// # Example
41    ///
42    /// Transposing a `Spanned<Enum<T>>` into `Enum<Spanned<T>>`:
43    ///
44    /// ```
45    /// use serde::de::{Deserialize, Deserializer};
46    /// use serde_untagged::UntaggedEnumVisitor;
47    /// use toml::Spanned;
48    ///
49    /// pub enum Dependency {
50    ///     Simple(Spanned<String>),
51    ///     Detailed(Spanned<DetailedDependency>),
52    /// }
53    ///
54    /// impl<'de> Deserialize<'de> for Dependency {
55    ///     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
56    ///     where
57    ///         D: Deserializer<'de>,
58    ///     {
59    ///         enum DependencyKind {
60    ///             Simple(String),
61    ///             Detailed(DetailedDependency),
62    ///         }
63    ///
64    ///         impl<'de> Deserialize<'de> for DependencyKind {
65    ///             fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
66    ///             where
67    ///                 D: Deserializer<'de>,
68    ///             {
69    ///                 UntaggedEnumVisitor::new()
70    ///                     .expecting(
71    ///                         "a version string like \"0.9.8\" or a \
72    ///                             detailed dependency like { version = \"0.9.8\" }",
73    ///                     )
74    ///                     .string(|value| Ok(DependencyKind::Simple(value.to_owned())))
75    ///                     .map(|value| value.deserialize().map(DependencyKind::Detailed))
76    ///                     .deserialize(deserializer)
77    ///             }
78    ///         }
79    ///
80    ///         let spanned: Spanned<DependencyKind> = Deserialize::deserialize(deserializer)?;
81    ///         let range = spanned.span();
82    ///         Ok(match spanned.into_inner() {
83    ///             DependencyKind::Simple(simple) => Dependency::Simple(Spanned::new(range, simple)),
84    ///             DependencyKind::Detailed(detailed) => Dependency::Detailed(Spanned::new(range, detailed)),
85    ///         })
86    ///     }
87    /// }
88    /// #
89    /// # type DetailedDependency = std::collections::BTreeMap<String, String>;
90    /// ```
91    pub fn new(range: std::ops::Range<usize>, value: T) -> Self {
92        Spanned { span: range, value }
93    }
94
95    /// Byte range
96    pub fn span(&self) -> std::ops::Range<usize> {
97        self.span.clone()
98    }
99
100    /// Consumes the spanned value and returns the contained value.
101    pub fn into_inner(self) -> T {
102        self.value
103    }
104
105    /// Returns a reference to the contained value.
106    pub fn get_ref(&self) -> &T {
107        &self.value
108    }
109
110    /// Returns a mutable reference to the contained value.
111    pub fn get_mut(&mut self) -> &mut T {
112        &mut self.value
113    }
114}
115
116impl std::borrow::Borrow<str> for Spanned<String> {
117    fn borrow(&self) -> &str {
118        self.get_ref()
119    }
120}
121
122impl<T> AsRef<T> for Spanned<T> {
123    fn as_ref(&self) -> &T {
124        self.get_ref()
125    }
126}
127
128impl<T> AsMut<T> for Spanned<T> {
129    fn as_mut(&mut self) -> &mut T {
130        self.get_mut()
131    }
132}
133
134impl<T: PartialEq> PartialEq for Spanned<T> {
135    fn eq(&self, other: &Self) -> bool {
136        self.value.eq(&other.value)
137    }
138}
139
140impl<T: Eq> Eq for Spanned<T> {}
141
142impl<T: Hash> Hash for Spanned<T> {
143    fn hash<H: Hasher>(&self, state: &mut H) {
144        self.value.hash(state);
145    }
146}
147
148impl<T: PartialOrd> PartialOrd for Spanned<T> {
149    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
150        self.value.partial_cmp(&other.value)
151    }
152}
153
154impl<T: Ord> Ord for Spanned<T> {
155    fn cmp(&self, other: &Self) -> Ordering {
156        self.value.cmp(&other.value)
157    }
158}
159
160#[cfg(feature = "serde")]
161impl<'de, T> serde::de::Deserialize<'de> for Spanned<T>
162where
163    T: serde::de::Deserialize<'de>,
164{
165    fn deserialize<D>(deserializer: D) -> Result<Spanned<T>, D::Error>
166    where
167        D: serde::de::Deserializer<'de>,
168    {
169        struct SpannedVisitor<T>(::std::marker::PhantomData<T>);
170
171        impl<'de, T> serde::de::Visitor<'de> for SpannedVisitor<T>
172        where
173            T: serde::de::Deserialize<'de>,
174        {
175            type Value = Spanned<T>;
176
177            fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
178                formatter.write_str("a spanned value")
179            }
180
181            fn visit_map<V>(self, mut visitor: V) -> Result<Spanned<T>, V::Error>
182            where
183                V: serde::de::MapAccess<'de>,
184            {
185                let mut start: Option<usize> = None;
186                let mut end: Option<usize> = None;
187                let mut value: Option<T> = None;
188                while let Some(key) = visitor.next_key()? {
189                    match key {
190                        START_FIELD => {
191                            if start.is_some() {
192                                return Err(serde::de::Error::duplicate_field(START_FIELD));
193                            }
194                            start = Some(visitor.next_value()?);
195                        }
196                        END_FIELD => {
197                            if end.is_some() {
198                                return Err(serde::de::Error::duplicate_field(END_FIELD));
199                            }
200                            end = Some(visitor.next_value()?);
201                        }
202                        VALUE_FIELD => {
203                            if value.is_some() {
204                                return Err(serde::de::Error::duplicate_field(VALUE_FIELD));
205                            }
206                            value = Some(visitor.next_value()?);
207                        }
208                        field => {
209                            return Err(serde::de::Error::unknown_field(
210                                field,
211                                &[START_FIELD, END_FIELD, VALUE_FIELD],
212                            ));
213                        }
214                    }
215                }
216                match (start, end, value) {
217                    (Some(start), Some(end), Some(value)) => Ok(Spanned {
218                        span: start..end,
219                        value,
220                    }),
221                    (None, _, _) => Err(serde::de::Error::missing_field(START_FIELD)),
222                    (_, None, _) => Err(serde::de::Error::missing_field(END_FIELD)),
223                    (_, _, None) => Err(serde::de::Error::missing_field(VALUE_FIELD)),
224                }
225            }
226        }
227
228        static FIELDS: [&str; 3] = [START_FIELD, END_FIELD, VALUE_FIELD];
229
230        let visitor = SpannedVisitor(::std::marker::PhantomData);
231
232        deserializer.deserialize_struct(NAME, &FIELDS, visitor)
233    }
234}
235
236#[cfg(feature = "serde")]
237impl<T: serde::ser::Serialize> serde::ser::Serialize for Spanned<T> {
238    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
239    where
240        S: serde::ser::Serializer,
241    {
242        self.value.serialize(serializer)
243    }
244}