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