serde_spanned/
spanned.rs

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