uri_parsing_rs/parser/
parsers.rs

1use nom::{IResult, Needed, Compare, CompareResult, InputTake, AsBytes, InputLength};
2
3use nom::error::{ErrorKind, ContextError, ParseError};
4
5use nom::lib::std::iter::{Copied, Enumerate};
6use nom::lib::std::ops::{Range, RangeFrom, RangeFull, RangeTo};
7use nom::lib::std::slice::Iter;
8
9use std::string::FromUtf8Error;
10use std::str::Utf8Error;
11use std::fmt::Formatter;
12
13pub mod authority_parsers;
14pub mod basic_parsers;
15pub mod fragment_parsers;
16pub mod hier_part_parsers;
17pub mod host_parsers;
18pub mod ipv4_address_parsers;
19pub mod ipv6_address_parsers;
20pub mod path_parsers;
21pub mod port_parsers;
22pub mod query_parsers;
23pub mod scheme_parsers;
24pub mod uri_parsers;
25pub mod user_info_parsers;
26
27/// Custom Input Type
28#[derive(Clone, PartialEq)]
29pub struct Elms<'a> {
30  values: &'a [u8],
31}
32
33impl<'a> std::fmt::Display for Elms<'a> {
34  fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35    write!(f, "{}", self.as_str().unwrap())
36  }
37}
38
39impl<'a> Elms<'a> {
40  pub fn new(values: &'a [u8]) -> Self {
41    Self { values }
42  }
43
44  pub fn as_str(&self) -> Result<&str, Utf8Error> {
45    std::str::from_utf8(self.values)
46  }
47
48  pub fn as_string(&self) -> Result<String, FromUtf8Error> {
49    String::from_utf8(self.as_bytes().to_vec())
50  }
51}
52
53impl<'a> nom::InputLength for Elms<'a> {
54  fn input_len(&self) -> usize {
55    self.values.len()
56  }
57}
58
59impl<'a> nom::AsBytes for Elms<'a> {
60  fn as_bytes(&self) -> &[u8] {
61    self.values
62  }
63}
64
65impl<'a> nom::InputTake for Elms<'a> {
66  fn take(&self, count: usize) -> Self {
67    let s = self.values.take(count);
68    Elms::new(s)
69  }
70
71  fn take_split(&self, count: usize) -> (Self, Self) {
72    let s = self.values.take_split(count);
73    (Elms::new(s.0), Elms::new(s.1))
74  }
75}
76
77impl<'a> nom::InputTakeAtPosition for Elms<'a> {
78  type Item = u8;
79
80  fn split_at_position<P, E: ParseError<Self>>(&self, predicate: P) -> IResult<Self, Self, E>
81  where
82    P: Fn(Self::Item) -> bool,
83  {
84    match self.values.iter().position(|c| predicate(*c)) {
85      Some(i) => Ok(self.take_split(i)),
86      None => Err(nom::Err::Incomplete(Needed::new(1))),
87    }
88  }
89
90  fn split_at_position1<P, E: ParseError<Self>>(
91    &self,
92    predicate: P,
93    e: ErrorKind,
94  ) -> IResult<Self, Self, E>
95  where
96    P: Fn(Self::Item) -> bool,
97  {
98    match self.values.iter().position(|c| predicate(*c)) {
99      Some(0) => Err(nom::Err::Error(E::from_error_kind(self.clone(), e))),
100      Some(i) => Ok(self.take_split(i)),
101      None => Err(nom::Err::Incomplete(Needed::new(1))),
102    }
103  }
104
105  fn split_at_position_complete<P, E: ParseError<Self>>(
106    &self,
107    predicate: P,
108  ) -> IResult<Self, Self, E>
109  where
110    P: Fn(Self::Item) -> bool,
111  {
112    match self.values.iter().position(|c| predicate(*c)) {
113      Some(i) => Ok(self.take_split(i)),
114      None => Ok(self.take_split(self.input_len())),
115    }
116  }
117
118  fn split_at_position1_complete<P, E: ParseError<Self>>(
119    &self,
120    predicate: P,
121    e: ErrorKind,
122  ) -> IResult<Self, Self, E>
123  where
124    P: Fn(Self::Item) -> bool,
125  {
126    match self.values.iter().position(|c| predicate(*c)) {
127      Some(0) => Err(nom::Err::Error(E::from_error_kind(self.clone(), e))),
128      Some(i) => Ok(self.take_split(i)),
129      None => {
130        if self.values.is_empty() {
131          Err(nom::Err::Error(E::from_error_kind(self.clone(), e)))
132        } else {
133          Ok(self.take_split(self.input_len()))
134        }
135      }
136    }
137  }
138}
139
140impl<'a, 'b> Compare<Elms<'b>> for Elms<'a> {
141  fn compare(&self, t: Elms<'b>) -> CompareResult {
142    self.values.compare(t.values)
143  }
144
145  fn compare_no_case(&self, t: Elms<'b>) -> CompareResult {
146    self.values.compare_no_case(t.values)
147  }
148}
149
150impl<'a, 'b> Compare<&'b str> for Elms<'a> {
151  #[inline(always)]
152  fn compare(&self, t: &'b str) -> CompareResult {
153    self.values.compare(AsBytes::as_bytes(t))
154  }
155  #[inline(always)]
156  fn compare_no_case(&self, t: &'b str) -> CompareResult {
157    self.values.compare_no_case(AsBytes::as_bytes(t))
158  }
159}
160
161/// InputIter for Elms
162///
163/// This type provides essentially the same implementation as &'a [u8].
164impl<'a> nom::InputIter for Elms<'a> {
165  type Item = u8;
166  type Iter = Enumerate<Self::IterElem>;
167  type IterElem = Copied<Iter<'a, u8>>;
168
169  fn iter_indices(&self) -> Self::Iter {
170    self.values.iter_indices()
171  }
172
173  fn iter_elements(&self) -> Self::IterElem {
174    self.values.iter_elements()
175  }
176
177  fn position<P>(&self, predicate: P) -> Option<usize>
178  where
179    P: Fn(Self::Item) -> bool,
180  {
181    self.values.position(predicate)
182  }
183
184  fn slice_index(&self, count: usize) -> Result<usize, Needed> {
185    self.values.slice_index(count)
186  }
187}
188
189impl<'a> nom::Slice<Range<usize>> for Elms<'a> {
190  fn slice(&self, range: Range<usize>) -> Self {
191    let s = &self.values[range];
192    Elms::new(s)
193  }
194}
195
196impl<'a> nom::Slice<RangeTo<usize>> for Elms<'a> {
197  fn slice(&self, range: RangeTo<usize>) -> Self {
198    let s = &self.values[range];
199    Elms::new(s)
200  }
201}
202
203impl<'a> nom::Slice<RangeFrom<usize>> for Elms<'a> {
204  fn slice(&self, range: RangeFrom<usize>) -> Self {
205    let s = &self.values[range];
206    Elms::new(s)
207  }
208}
209
210impl<'a> nom::Slice<RangeFull> for Elms<'a> {
211  fn slice(&self, range: RangeFull) -> Self {
212    let s = &self.values[range];
213    Elms::new(s)
214  }
215}
216
217/// Custom parse error type.
218#[derive(Debug, PartialEq)]
219pub struct UriParseError {
220  message: String,
221}
222
223impl ContextError<Elms<'_>> for UriParseError {
224  fn add_context(_input: Elms, _ctx: &'static str, other: Self) -> Self {
225    other
226  }
227}
228
229impl ParseError<Elms<'_>> for UriParseError {
230  fn from_error_kind(input: Elms, kind: ErrorKind) -> Self {
231    let input = input.as_str().unwrap();
232    let message = format!("{:?}:\t{:?}\n", kind, input);
233    Self { message }
234  }
235
236  fn append(input: Elms, kind: ErrorKind, other: Self) -> Self {
237    let input = input.as_str().unwrap();
238    let message = format!("{}{:?}:\t{:?}\n", other.message, kind, input);
239    Self { message }
240  }
241
242  fn from_char(input: Elms, c: char) -> Self {
243    let input = input.as_str().unwrap();
244    let message = format!("'{}':\t{:?}\n", c, input);
245    Self { message }
246  }
247
248  fn or(self, other: Self) -> Self {
249    let message = format!("{}\tOR\n{}\n", self.message, other.message);
250    Self { message }
251  }
252}
253
254pub type UResult<T, U> = IResult<T, U, UriParseError>;