• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::cmp::Ordering;
2 use 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")]
12 pub const NAME: &str = "$__serde_spanned_private_Spanned";
13 #[doc(hidden)]
14 #[cfg(feature = "serde")]
15 pub const START_FIELD: &str = "$__serde_spanned_private_start";
16 #[doc(hidden)]
17 #[cfg(feature = "serde")]
18 pub const END_FIELD: &str = "$__serde_spanned_private_end";
19 #[doc(hidden)]
20 #[cfg(feature = "serde")]
21 pub const VALUE_FIELD: &str = "$__serde_spanned_private_value";
22 #[doc(hidden)]
23 #[cfg(feature = "serde")]
is_spanned(name: &'static str, fields: &'static [&'static str]) -> bool24 pub 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)]
30 pub struct Spanned<T> {
31     /// Byte range
32     span: std::ops::Range<usize>,
33     /// The spanned value.
34     value: T,
35 }
36 
37 impl<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     /// ```
new(range: std::ops::Range<usize>, value: T) -> Self91     pub fn new(range: std::ops::Range<usize>, value: T) -> Self {
92         Spanned { span: range, value }
93     }
94 
95     /// Byte range
span(&self) -> std::ops::Range<usize>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.
into_inner(self) -> T101     pub fn into_inner(self) -> T {
102         self.value
103     }
104 
105     /// Returns a reference to the contained value.
get_ref(&self) -> &T106     pub fn get_ref(&self) -> &T {
107         &self.value
108     }
109 
110     /// Returns a mutable reference to the contained value.
get_mut(&mut self) -> &mut T111     pub fn get_mut(&mut self) -> &mut T {
112         &mut self.value
113     }
114 }
115 
116 impl std::borrow::Borrow<str> for Spanned<String> {
borrow(&self) -> &str117     fn borrow(&self) -> &str {
118         self.get_ref()
119     }
120 }
121 
122 impl<T> AsRef<T> for Spanned<T> {
as_ref(&self) -> &T123     fn as_ref(&self) -> &T {
124         self.get_ref()
125     }
126 }
127 
128 impl<T> AsMut<T> for Spanned<T> {
as_mut(&mut self) -> &mut T129     fn as_mut(&mut self) -> &mut T {
130         self.get_mut()
131     }
132 }
133 
134 impl<T: PartialEq> PartialEq for Spanned<T> {
eq(&self, other: &Self) -> bool135     fn eq(&self, other: &Self) -> bool {
136         self.value.eq(&other.value)
137     }
138 }
139 
140 impl<T: Eq> Eq for Spanned<T> {}
141 
142 impl<T: Hash> Hash for Spanned<T> {
hash<H: Hasher>(&self, state: &mut H)143     fn hash<H: Hasher>(&self, state: &mut H) {
144         self.value.hash(state);
145     }
146 }
147 
148 impl<T: PartialOrd> PartialOrd for Spanned<T> {
partial_cmp(&self, other: &Self) -> Option<Ordering>149     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
150         self.value.partial_cmp(&other.value)
151     }
152 }
153 
154 impl<T: Ord> Ord for Spanned<T> {
cmp(&self, other: &Self) -> Ordering155     fn cmp(&self, other: &Self) -> Ordering {
156         self.value.cmp(&other.value)
157     }
158 }
159 
160 #[cfg(feature = "serde")]
161 impl<'de, T> serde::de::Deserialize<'de> for Spanned<T>
162 where
163     T: serde::de::Deserialize<'de>,
164 {
deserialize<D>(deserializer: D) -> Result<Spanned<T>, D::Error> where D: serde::de::Deserializer<'de>,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")]
237 impl<T: serde::ser::Serialize> serde::ser::Serialize for Spanned<T> {
serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: serde::ser::Serializer,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 }
245