toml_span/
span.rs

1//! Provides span helpers
2
3/// A start and end location within a toml document
4#[derive(Copy, Clone, PartialEq, Eq, Default, Debug)]
5pub struct Span {
6    /// The start byte index
7    pub start: usize,
8    /// The end (exclusive) byte index
9    pub end: usize,
10}
11
12impl Span {
13    /// Creates a new [`Span`]
14    #[inline]
15    pub fn new(start: usize, end: usize) -> Self {
16        Self { start, end }
17    }
18
19    /// Checks if the start and end are the same, and thus the span is empty
20    #[inline]
21    pub fn is_empty(&self) -> bool {
22        self.start == 0 && self.end == 0
23    }
24}
25
26impl From<Span> for (usize, usize) {
27    fn from(Span { start, end }: Span) -> (usize, usize) {
28        (start, end)
29    }
30}
31
32impl From<std::ops::Range<usize>> for Span {
33    fn from(s: std::ops::Range<usize>) -> Self {
34        Self {
35            start: s.start,
36            end: s.end,
37        }
38    }
39}
40
41impl From<Span> for std::ops::Range<usize> {
42    fn from(s: Span) -> Self {
43        Self {
44            start: s.start,
45            end: s.end,
46        }
47    }
48}
49
50/// An arbitrary `T` with additional span information
51pub struct Spanned<T> {
52    /// The value
53    pub value: T,
54    /// The span information for the value
55    pub span: Span,
56}
57
58impl<T> Spanned<T> {
59    /// Creates a [`Spanned`] with just the value and an empty [`Span`]
60    #[inline]
61    pub const fn new(value: T) -> Self {
62        Self {
63            value,
64            span: Span { start: 0, end: 0 },
65        }
66    }
67
68    /// Creates a [`Spanned`] from both a value and a [`Span`]
69    #[inline]
70    pub const fn with_span(value: T, span: Span) -> Self {
71        Self { value, span }
72    }
73
74    /// Converts [`Self`] into its inner value
75    #[inline]
76    pub fn take(self) -> T {
77        self.value
78    }
79
80    /// Helper to convert the value inside the Spanned
81    #[inline]
82    pub fn map<V>(self) -> Spanned<V>
83    where
84        V: From<T>,
85    {
86        Spanned {
87            value: self.value.into(),
88            span: self.span,
89        }
90    }
91}
92
93impl<T> Default for Spanned<T>
94where
95    T: Default,
96{
97    fn default() -> Self {
98        Self {
99            value: Default::default(),
100            span: Span::default(),
101        }
102    }
103}
104
105impl<T> AsRef<T> for Spanned<T> {
106    fn as_ref(&self) -> &T {
107        &self.value
108    }
109}
110
111impl<T> std::fmt::Debug for Spanned<T>
112where
113    T: std::fmt::Debug,
114{
115    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116        write!(f, "{:?}", self.value)
117    }
118}
119
120impl<T> Clone for Spanned<T>
121where
122    T: Clone,
123{
124    fn clone(&self) -> Self {
125        Self {
126            value: self.value.clone(),
127            span: self.span,
128        }
129    }
130}
131
132impl<T> PartialOrd for Spanned<T>
133where
134    T: PartialOrd,
135{
136    fn partial_cmp(&self, o: &Spanned<T>) -> Option<std::cmp::Ordering> {
137        self.value.partial_cmp(&o.value)
138    }
139}
140
141impl<T> Ord for Spanned<T>
142where
143    T: Ord,
144{
145    fn cmp(&self, o: &Spanned<T>) -> std::cmp::Ordering {
146        self.value.cmp(&o.value)
147    }
148}
149
150impl<T> PartialEq for Spanned<T>
151where
152    T: PartialEq,
153{
154    fn eq(&self, o: &Spanned<T>) -> bool {
155        self.value == o.value
156    }
157}
158
159impl<T> Eq for Spanned<T> where T: Eq {}
160
161impl<T> PartialEq<T> for Spanned<T>
162where
163    T: PartialEq,
164{
165    fn eq(&self, o: &T) -> bool {
166        &self.value == o
167    }
168}
169
170impl<'de, T> crate::Deserialize<'de> for Spanned<T>
171where
172    T: crate::Deserialize<'de>,
173{
174    #[inline]
175    fn deserialize(value: &mut crate::value::Value<'de>) -> Result<Self, crate::DeserError> {
176        let span = value.span;
177        let value = T::deserialize(value)?;
178        Ok(Self { span, value })
179    }
180}