1use musli::de::NumberVisitor;
2use musli::{Buf, Context};
3
4use crate::parser::integer::decode_signed_full;
5use crate::parser::{string, StringReference, Token};
6
7mod private {
8 pub trait Sealed {}
9 impl<'de> Sealed for crate::parser::SliceParser<'de> {}
10 impl<'de, R> Sealed for &mut R where R: ?Sized + super::Parser<'de> {}
11}
12
13pub trait Parser<'de>: private::Sealed {
15 type Mut<'this>: Parser<'de>
25 where
26 Self: 'this;
27
28 fn borrow_mut(&mut self) -> Self::Mut<'_>;
30
31 #[doc(hidden)]
34 fn parse_string<'scratch, C, S>(
35 &mut self,
36 cx: &C,
37 validate: bool,
38 scratch: &'scratch mut S,
39 ) -> Result<StringReference<'de, 'scratch>, C::Error>
40 where
41 C: ?Sized + Context,
42 S: ?Sized + Buf;
43
44 #[doc(hidden)]
45 fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
46 where
47 C: ?Sized + Context;
48
49 #[doc(hidden)]
50 fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
51 where
52 C: ?Sized + Context;
53
54 #[doc(hidden)]
55 fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
56 where
57 C: ?Sized + Context;
58
59 #[doc(hidden)]
60 fn pos(&self) -> u32;
61
62 #[doc(hidden)]
64 fn skip_whitespace<C>(&mut self, cx: &C) -> Result<(), C::Error>
65 where
66 C: ?Sized + Context;
67
68 #[doc(hidden)]
70 fn peek_byte<C>(&mut self, cx: &C) -> Result<Option<u8>, C::Error>
71 where
72 C: ?Sized + Context;
73
74 #[doc(hidden)]
75 fn consume_while<C>(&mut self, cx: &C, m: fn(u8) -> bool) -> Result<usize, C::Error>
76 where
77 C: ?Sized + Context,
78 {
79 let mut c = 0;
80
81 while let Some(b) = self.peek_byte(cx)? {
82 if !m(b) {
83 return Ok(c);
84 }
85
86 c += 1;
87 self.skip(cx, 1)?;
88 }
89
90 Ok(c)
91 }
92
93 #[doc(hidden)]
94 fn peek<C>(&mut self, cx: &C) -> Result<Token, C::Error>
95 where
96 C: ?Sized + Context,
97 {
98 self.skip_whitespace(cx)?;
99
100 let b = match self.peek_byte(cx)? {
101 Some(b) => b,
102 None => return Ok(Token::Eof),
103 };
104
105 Ok(Token::from_byte(b))
106 }
107
108 fn parse_f32<C>(&mut self, cx: &C) -> Result<f32, C::Error>
110 where
111 C: ?Sized + Context;
112
113 fn parse_f64<C>(&mut self, cx: &C) -> Result<f64, C::Error>
115 where
116 C: ?Sized + Context;
117
118 #[doc(hidden)]
119 fn parse_hex_escape<C>(&mut self, cx: &C) -> Result<u16, C::Error>
120 where
121 C: ?Sized + Context,
122 {
123 let mut n = 0;
124 let start = cx.mark();
125
126 for _ in 0..4 {
127 match string::decode_hex_val(self.read_byte(cx)?) {
128 None => {
129 return Err(cx.marked_message(start, "Invalid string escape"));
130 }
131 Some(val) => {
132 n = (n << 4) + val;
133 }
134 }
135 }
136
137 Ok(n)
138 }
139
140 #[doc(hidden)]
141 fn parse_exact<C>(&mut self, cx: &C, exact: &str) -> Result<(), C::Error>
142 where
143 C: ?Sized + Context,
144 {
145 debug_assert!(exact.len() <= 5);
146
147 let mark = cx.mark();
148
149 let mut bytes = [0u8; 8];
150 let bytes = &mut bytes[..exact.len()];
151
152 self.read(cx, bytes)?;
153
154 if bytes != exact.as_bytes() {
155 return Err(cx.marked_message(mark, format_args!("Expected `{exact}`")));
156 }
157
158 Ok(())
159 }
160
161 #[doc(hidden)]
164 fn parse_number<C, V>(&mut self, cx: &C, visitor: V) -> Result<V::Ok, C::Error>
165 where
166 C: ?Sized + Context,
167 V: NumberVisitor<'de, C>,
168 {
169 let signed = decode_signed_full::<i128, _, _>(cx, self)?;
170
171 if signed.is_negative {
172 let value = match signed.compute() {
173 Ok(value) => value,
174 Err(..) => {
175 let value = signed.compute_float();
176 return visitor.visit_f64(cx, value);
177 }
178 };
179
180 if value >= i8::MIN as i128 && value <= i8::MAX as i128 {
181 return visitor.visit_i8(cx, value as i8);
182 }
183
184 if value >= i16::MIN as i128 && value <= i16::MAX as i128 {
185 return visitor.visit_i16(cx, value as i16);
186 }
187
188 if value >= i32::MIN as i128 && value <= i32::MAX as i128 {
189 return visitor.visit_i32(cx, value as i32);
190 }
191
192 if value >= i64::MIN as i128 && value <= i64::MAX as i128 {
193 return visitor.visit_i64(cx, value as i64);
194 }
195
196 if value >= isize::MIN as i128 && value <= isize::MAX as i128 {
197 return visitor.visit_isize(cx, value as isize);
198 }
199
200 visitor.visit_i128(cx, value)
201 } else {
202 let value = match signed.unsigned.compute() {
203 Ok(value) => value,
204 Err(..) => {
205 let value = signed.unsigned.compute_float();
206 return visitor.visit_f64(cx, value);
207 }
208 };
209
210 if value <= u8::MAX as u128 {
211 return visitor.visit_u8(cx, value as u8);
212 }
213
214 if value <= u16::MAX as u128 {
215 return visitor.visit_u16(cx, value as u16);
216 }
217
218 if value <= u32::MAX as u128 {
219 return visitor.visit_u32(cx, value as u32);
220 }
221
222 if value <= u64::MAX as u128 {
223 return visitor.visit_u64(cx, value as u64);
224 }
225
226 if value <= usize::MAX as u128 {
227 return visitor.visit_usize(cx, value as usize);
228 }
229
230 visitor.visit_u128(cx, value)
231 }
232 }
233}
234
235impl<'de, P> Parser<'de> for &mut P
236where
237 P: ?Sized + Parser<'de>,
238{
239 type Mut<'this> = P::Mut<'this> where Self: 'this;
240
241 #[inline(always)]
242 fn borrow_mut(&mut self) -> Self::Mut<'_> {
243 (**self).borrow_mut()
244 }
245
246 #[inline(always)]
247 fn parse_string<'scratch, C, S>(
248 &mut self,
249 cx: &C,
250 validate: bool,
251 scratch: &'scratch mut S,
252 ) -> Result<StringReference<'de, 'scratch>, C::Error>
253 where
254 C: ?Sized + Context,
255 S: ?Sized + Buf,
256 {
257 (**self).parse_string(cx, validate, scratch)
258 }
259
260 #[inline(always)]
261 fn read_byte<C>(&mut self, cx: &C) -> Result<u8, C::Error>
262 where
263 C: ?Sized + Context,
264 {
265 (**self).read_byte(cx)
266 }
267
268 #[inline(always)]
269 fn peek<C>(&mut self, cx: &C) -> Result<Token, C::Error>
270 where
271 C: ?Sized + Context,
272 {
273 (**self).peek(cx)
274 }
275
276 #[inline(always)]
277 fn pos(&self) -> u32 {
278 (**self).pos()
279 }
280
281 #[inline(always)]
282 fn skip_whitespace<C>(&mut self, cx: &C) -> Result<(), C::Error>
283 where
284 C: ?Sized + Context,
285 {
286 (**self).skip_whitespace(cx)
287 }
288
289 #[inline(always)]
290 fn peek_byte<C>(&mut self, cx: &C) -> Result<Option<u8>, C::Error>
291 where
292 C: ?Sized + Context,
293 {
294 (**self).peek_byte(cx)
295 }
296
297 #[inline(always)]
298 fn skip<C>(&mut self, cx: &C, n: usize) -> Result<(), C::Error>
299 where
300 C: ?Sized + Context,
301 {
302 (**self).skip(cx, n)
303 }
304
305 #[inline(always)]
306 fn read<C>(&mut self, cx: &C, buf: &mut [u8]) -> Result<(), C::Error>
307 where
308 C: ?Sized + Context,
309 {
310 (**self).read(cx, buf)
311 }
312
313 #[inline(always)]
314 fn parse_f32<C>(&mut self, cx: &C) -> Result<f32, C::Error>
315 where
316 C: ?Sized + Context,
317 {
318 (**self).parse_f32(cx)
319 }
320
321 #[inline(always)]
322 fn parse_f64<C>(&mut self, cx: &C) -> Result<f64, C::Error>
323 where
324 C: ?Sized + Context,
325 {
326 (**self).parse_f64(cx)
327 }
328}