facet_deserialize/
span.rs1use alloc::vec::Vec;
2use core::fmt;
3use core::marker::PhantomData;
4
5#[derive(Debug, PartialEq)]
7pub enum Cooked {}
8
9#[derive(Debug, PartialEq)]
11pub enum Raw {}
12
13pub type Pos = usize;
15
16#[derive(Debug, PartialEq, Eq)]
18pub struct Span<C = Cooked> {
19 pub start: Pos,
21 pub len: usize,
23 _p: PhantomData<C>,
25}
26
27pub trait Spannable<C = Cooked>: Sized {
29 fn with_span(self, span: Span<C>) -> Spanned<Self, C>;
31}
32
33impl<T, C> Spannable<C> for T {
34 fn with_span(self, span: Span<C>) -> Spanned<Self, C> {
35 Spanned { node: self, span }
36 }
37}
38
39impl<C> Span<C> {
40 pub fn new(start: Pos, len: usize) -> Self {
42 Span {
43 start,
44 len,
45 _p: PhantomData,
46 }
47 }
48 pub fn start(&self) -> Pos {
50 self.start
51 }
52 pub fn len(&self) -> usize {
54 self.len
55 }
56 pub fn is_empty(&self) -> bool {
58 self.len == 0
59 }
60 pub fn end(&self) -> Pos {
62 self.start + self.len
63 }
64}
65
66impl<C> Default for Span<C> {
67 fn default() -> Self {
68 Span {
69 start: 0,
70 len: 0,
71 _p: PhantomData,
72 }
73 }
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct Spanned<T, C = Cooked> {
79 pub node: T,
81 pub span: Span<C>,
83}
84
85impl<T: fmt::Display, C> fmt::Display for Spanned<T, C> {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 write!(
88 f,
89 "{} at {}-{}",
90 self.node,
91 self.span.start(),
92 self.span.end()
93 )
94 }
95}
96
97impl<C> Clone for Span<C> {
101 fn clone(&self) -> Self {
102 *self
103 }
104}
105
106impl<C> Copy for Span<C> {}
107
108#[derive(Debug, PartialEq)]
110pub struct Subspan {
111 pub offset: usize,
113 pub len: usize,
115 pub meta: Option<SubspanMeta>,
117}
118
119#[derive(Debug, Clone, PartialEq)]
122pub enum SubspanMeta {
123 Delimiter(char),
126
127 KeyValue,
130 }
132
133pub struct Substack<C> {
135 spans: Option<Vec<Subspan>>,
136 _marker: PhantomData<C>,
137}
138
139impl<C> Substack<C> {
140 pub fn new() -> Self {
142 Substack {
143 spans: None,
144 _marker: PhantomData,
145 }
146 }
147
148 pub fn get(&self) -> &[Subspan] {
150 match &self.spans {
151 Some(spans) => spans,
152 None => &[], }
154 }
155}
156
157impl<C> Default for Substack<C> {
158 fn default() -> Self {
159 Self::new()
160 }
161}
162
163impl Substack<Raw> {
164 pub fn add(&mut self, offset: usize, len: usize, meta: Option<SubspanMeta>) {
166 if self.spans.is_none() {
167 self.spans = Some(Vec::new());
168 }
169
170 if let Some(spans) = &mut self.spans {
171 spans.push(Subspan { offset, len, meta });
172 }
173 }
174
175 pub fn add_simple(&mut self, offset: usize, len: usize) {
177 self.add(offset, len, None);
178 }
179
180 pub fn add_delimiter(&mut self, offset: usize, len: usize, delimiter: char) {
182 self.add(offset, len, Some(SubspanMeta::Delimiter(delimiter)));
183 }
184
185 pub fn add_key_value(&mut self, offset: usize, len: usize) {
187 self.add(offset, len, Some(SubspanMeta::KeyValue));
188 }
189}
190
191impl Substack<Cooked> {
192 pub fn add(&mut self, _offset: usize, _len: usize, _meta: Option<SubspanMeta>) {}
194
195 pub fn add_simple(&mut self, _offset: usize, _len: usize) {}
197
198 pub fn add_delimiter(&mut self, _offset: usize, _len: usize, _delimiter: char) {}
200
201 pub fn add_key_value(&mut self, _offset: usize, _len: usize) {}
203}