kdl_script/
spanned.rs

1use std::{
2    borrow::Borrow,
3    cmp::Ordering,
4    fmt::{self, Display},
5    hash::{Hash, Hasher},
6    ops::{Deref, DerefMut},
7};
8
9use miette::SourceSpan;
10use serde::{ser, Deserialize};
11
12/// A spanned value, indicating the range at which it is defined in the source.
13#[derive(Clone, Default, Deserialize)]
14pub struct Spanned<T> {
15    start: usize,
16    end: usize,
17    value: T,
18}
19
20impl<T> Spanned<T> {
21    pub fn new(value: T, span: SourceSpan) -> Self {
22        Self {
23            value,
24            start: span.offset(),
25            end: span.offset() + span.len(),
26        }
27    }
28
29    /// Access the start of the span of the contained value.
30    pub fn start(this: &Self) -> usize {
31        this.start
32    }
33
34    /// Access the end of the span of the contained value.
35    pub fn end(this: &Self) -> usize {
36        this.end
37    }
38
39    // Acquire the span of the input
40    pub fn clone_span_from<U>(this: &mut Self, other: &Spanned<U>) {
41        this.start = other.start;
42        this.end = other.end;
43    }
44
45    /// Update the span
46    pub fn update_span(this: &mut Self, start: usize, end: usize) {
47        this.start = start;
48        this.end = end;
49    }
50
51    /// Get the span of the contained value.
52    pub fn span(this: &Self) -> SourceSpan {
53        (Self::start(this)..Self::end(this)).into()
54    }
55
56    /// Consumes the spanned value and returns the contained value.
57    pub fn into_inner(this: Self) -> T {
58        this.value
59    }
60}
61
62impl<T> IntoIterator for Spanned<T>
63where
64    T: IntoIterator,
65{
66    type IntoIter = T::IntoIter;
67    type Item = T::Item;
68    fn into_iter(self) -> Self::IntoIter {
69        self.value.into_iter()
70    }
71}
72
73impl<'a, T> IntoIterator for &'a Spanned<T>
74where
75    &'a T: IntoIterator,
76{
77    type IntoIter = <&'a T as IntoIterator>::IntoIter;
78    type Item = <&'a T as IntoIterator>::Item;
79    fn into_iter(self) -> Self::IntoIter {
80        self.value.into_iter()
81    }
82}
83
84impl<'a, T> IntoIterator for &'a mut Spanned<T>
85where
86    &'a mut T: IntoIterator,
87{
88    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
89    type Item = <&'a mut T as IntoIterator>::Item;
90    fn into_iter(self) -> Self::IntoIter {
91        self.value.into_iter()
92    }
93}
94
95impl<T> fmt::Debug for Spanned<T>
96where
97    T: fmt::Debug,
98{
99    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100        self.value.fmt(f)
101    }
102}
103
104impl<T> Display for Spanned<T>
105where
106    T: Display,
107{
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        self.value.fmt(f)
110    }
111}
112
113impl<T> Deref for Spanned<T> {
114    type Target = T;
115    fn deref(&self) -> &Self::Target {
116        &self.value
117    }
118}
119
120impl<T> DerefMut for Spanned<T> {
121    fn deref_mut(&mut self) -> &mut Self::Target {
122        &mut self.value
123    }
124}
125
126impl Borrow<str> for Spanned<String> {
127    fn borrow(&self) -> &str {
128        self
129    }
130}
131
132impl<T, U: ?Sized> AsRef<U> for Spanned<T>
133where
134    T: AsRef<U>,
135{
136    fn as_ref(&self) -> &U {
137        self.value.as_ref()
138    }
139}
140
141impl<T: PartialEq> PartialEq for Spanned<T> {
142    fn eq(&self, other: &Self) -> bool {
143        self.value.eq(&other.value)
144    }
145}
146
147impl<T: PartialEq<T>> PartialEq<T> for Spanned<T> {
148    fn eq(&self, other: &T) -> bool {
149        self.value.eq(other)
150    }
151}
152
153impl PartialEq<str> for Spanned<String> {
154    fn eq(&self, other: &str) -> bool {
155        self.value.eq(other)
156    }
157}
158
159impl<T: Eq> Eq for Spanned<T> {}
160
161impl<T: Hash> Hash for Spanned<T> {
162    fn hash<H: Hasher>(&self, state: &mut H) {
163        self.value.hash(state);
164    }
165}
166
167impl<T: PartialOrd> PartialOrd for Spanned<T> {
168    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
169        self.value.partial_cmp(&other.value)
170    }
171}
172
173impl<T: PartialOrd<T>> PartialOrd<T> for Spanned<T> {
174    fn partial_cmp(&self, other: &T) -> Option<Ordering> {
175        self.value.partial_cmp(other)
176    }
177}
178
179impl<T: Ord> Ord for Spanned<T> {
180    fn cmp(&self, other: &Self) -> Ordering {
181        self.value.cmp(&other.value)
182    }
183}
184
185impl<T> From<T> for Spanned<T> {
186    fn from(value: T) -> Self {
187        Self {
188            start: 0,
189            end: 0,
190            value,
191        }
192    }
193}
194
195impl<T: ser::Serialize> ser::Serialize for Spanned<T> {
196    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
197    where
198        S: ser::Serializer,
199    {
200        self.value.serialize(serializer)
201    }
202}