fapolicy_rules/parser/
trace.rs1use nom::error::{ErrorKind, ParseError};
10use nom::{
11 AsBytes, Compare, CompareResult, FindSubstring, IResult, InputIter, InputLength, InputTake,
12 InputTakeAtPosition, Needed, Offset, Slice,
13};
14use std::ops::{RangeFrom, RangeTo};
15
16pub trait Position {
17 fn position(&self) -> usize;
18}
19
20#[derive(Debug, Copy, Clone)]
23pub struct Trace<I> {
24 pub current: I,
26 original: I,
28 pub position: usize,
30}
31
32impl<I> Trace<I>
33where
34 I: AsBytes + Clone,
35{
36 pub fn new(i: I) -> Self {
37 Trace {
38 current: i.clone(),
39 original: i,
40 position: 0,
41 }
42 }
43
44 pub fn is_empty(&self) -> bool {
45 self.as_bytes().is_empty()
46 }
47}
48
49impl<I: PartialEq> PartialEq for Trace<I> {
50 fn eq(&self, other: &Self) -> bool {
51 self.current == other.current
52 }
53}
54
55impl<I> Position for Trace<I> {
58 fn position(&self) -> usize {
59 self.position
60 }
61}
62
63impl<I: Offset> Offset for Trace<I> {
66 fn offset(&self, second: &Self) -> usize {
67 self.current.offset(&second.current)
68 }
69}
70
71impl<I: InputLength> InputLength for Trace<I> {
72 fn input_len(&self) -> usize {
73 self.current.input_len()
74 }
75}
76
77impl<'a, I> InputIter for Trace<I>
78where
79 I: InputIter,
80{
81 type Item = I::Item;
82 type Iter = I::Iter;
83 type IterElem = I::IterElem;
84
85 fn iter_indices(&self) -> Self::Iter {
86 self.current.iter_indices()
87 }
88
89 fn iter_elements(&self) -> Self::IterElem {
90 self.current.iter_elements()
91 }
92
93 fn position<P>(&self, predicate: P) -> Option<usize>
94 where
95 P: Fn(Self::Item) -> bool,
96 {
97 self.current.position(predicate)
98 }
99
100 fn slice_index(&self, count: usize) -> Result<usize, Needed> {
101 self.current.slice_index(count)
102 }
103}
104
105impl<I> InputTake for Trace<I>
106where
107 Self: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
108{
109 fn take(&self, count: usize) -> Self {
110 self.slice(..count)
111 }
112
113 fn take_split(&self, count: usize) -> (Self, Self) {
114 (self.slice(count..), self.slice(..count))
115 }
116}
117
118impl<T: AsBytes> AsBytes for Trace<T> {
119 fn as_bytes(&self) -> &[u8] {
120 self.current.as_bytes()
121 }
122}
123
124impl<'a, I, R> Slice<R> for Trace<I>
125where
126 I: Slice<R> + Offset + AsBytes + Slice<RangeTo<usize>> + Clone,
127{
128 fn slice(&self, range: R) -> Self {
129 let current = self.current.slice(range);
130 let position = self.original.as_bytes().len() - current.as_bytes().len();
131 Trace {
132 original: self.original.clone(),
133 current,
134 position,
135 }
136 }
137}
138
139impl<T: AsBytes + Clone> From<T> for Trace<T> {
140 fn from(i: T) -> Self {
141 Self::new(i)
142 }
143}
144
145impl<T, U> FindSubstring<U> for Trace<T>
146where
147 T: FindSubstring<U>,
148{
149 #[inline]
150 fn find_substring(&self, substr: U) -> Option<usize> {
151 self.current.find_substring(substr)
152 }
153}
154
155impl<T: InputLength + InputIter + InputTake + Clone> InputTakeAtPosition for Trace<T>
156where
157 T: InputTakeAtPosition + InputLength + InputIter,
158 Self: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Clone,
159{
160 type Item = <T as InputIter>::Item;
161
162 fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
163 where
164 P: Fn(Self::Item) -> bool,
165 {
166 match self.current.position(predicate) {
167 Some(n) => Ok(self.take_split(n)),
168 None => Err(nom::Err::Incomplete(nom::Needed::new(1))),
169 }
170 }
171
172 fn split_at_position1<P, E: ParseError<Self>>(
173 &self,
174 _predicate: P,
175 _e: ErrorKind,
176 ) -> IResult<Self, Self, E>
177 where
178 P: Fn(Self::Item) -> bool,
179 {
180 todo!()
181 }
182
183 fn split_at_position_complete<P, E: ParseError<Self>>(
184 &self,
185 predicate: P,
186 ) -> IResult<Self, Self, E>
187 where
188 P: Fn(Self::Item) -> bool,
189 {
190 match self.split_at_position(predicate) {
191 Err(nom::Err::Incomplete(_)) => Ok(self.take_split(self.input_len())),
192 res => res,
193 }
194 }
195
196 fn split_at_position1_complete<P, E: ParseError<Self>>(
197 &self,
198 predicate: P,
199 e: ErrorKind,
200 ) -> IResult<Self, Self, E>
201 where
202 P: Fn(Self::Item) -> bool,
203 {
204 match self.current.position(predicate) {
205 Some(0) => Err(nom::Err::Error(E::from_error_kind(self.clone(), e))),
206 Some(n) => Ok(self.take_split(n)),
207 None => {
208 if self.current.input_len() == 0 {
209 Err(nom::Err::Error(E::from_error_kind(self.clone(), e)))
210 } else {
211 Ok(self.take_split(self.input_len()))
212 }
213 }
214 }
215 }
216}
217
218impl<T: Compare<B>, B: Into<Trace<B>>> Compare<B> for Trace<T> {
219 fn compare(&self, t: B) -> CompareResult {
220 self.current.compare(t.into().current)
221 }
222
223 fn compare_no_case(&self, t: B) -> CompareResult {
224 self.current.compare_no_case(t.into().current)
225 }
226}
227
228#[cfg(test)]
229mod tests {
230 #[test]
231 fn trace_tag() {
232 }
234}