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#[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
161impl<'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#[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>;