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 if visitor.next_key()? != Some(START_FIELD) {
186 return Err(serde::de::Error::custom("spanned start key not found"));
187 }
188 let start: usize = visitor.next_value()?;
189
190 if visitor.next_key()? != Some(END_FIELD) {
191 return Err(serde::de::Error::custom("spanned end key not found"));
192 }
193 let end: usize = visitor.next_value()?;
194
195 if visitor.next_key()? != Some(VALUE_FIELD) {
196 return Err(serde::de::Error::custom("spanned value key not found"));
197 }
198 let value: T = visitor.next_value()?;
199
200 Ok(Spanned {
201 span: start..end,
202 value,
203 })
204 }
205 }
206
207 let visitor = SpannedVisitor(::std::marker::PhantomData);
208
209 static FIELDS: [&str; 3] = [START_FIELD, END_FIELD, VALUE_FIELD];
210 deserializer.deserialize_struct(NAME, &FIELDS, visitor)
211 }
212}
213
214#[cfg(feature = "serde")]
215impl<T: serde::ser::Serialize> serde::ser::Serialize for Spanned<T> {
216 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
217 where
218 S: serde::ser::Serializer,
219 {
220 self.value.serialize(serializer)
221 }
222}
223