/src/nom/src/number/mod.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! Parsers recognizing numbers |
2 | | |
3 | | use core::{ |
4 | | marker::PhantomData, |
5 | | ops::{Add, Shl}, |
6 | | }; |
7 | | |
8 | | use crate::{ |
9 | | branch::alt, |
10 | | character::{char, digit1}, |
11 | | combinator::{cut, map, opt, recognize}, |
12 | | error::{make_error, ErrorKind, ParseError}, |
13 | | sequence::pair, |
14 | | AsBytes, AsChar, Compare, Either, Emit, Err, Input, IsStreaming, Mode, Needed, Offset, OutputM, |
15 | | Parser, |
16 | | }; |
17 | | |
18 | | pub mod complete; |
19 | | pub mod streaming; |
20 | | |
21 | | /// Configurable endianness |
22 | | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
23 | | pub enum Endianness { |
24 | | /// Big endian |
25 | | Big, |
26 | | /// Little endian |
27 | | Little, |
28 | | /// Will match the host's endianness |
29 | | Native, |
30 | | } |
31 | | |
32 | | /// creates a big endian unsigned integer parser |
33 | | /// |
34 | | /// * `bound`: the number of bytes that will be read |
35 | | /// * `Uint`: the output type |
36 | | #[inline] |
37 | 0 | fn be_uint<I, Uint, E: ParseError<I>>(bound: usize) -> impl Parser<I, Output = Uint, Error = E> |
38 | 0 | where |
39 | 0 | I: Input<Item = u8>, |
40 | 0 | Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>, |
41 | 0 | { |
42 | 0 | BeUint { |
43 | 0 | bound, |
44 | 0 | e: PhantomData, |
45 | 0 | u: PhantomData, |
46 | 0 | } |
47 | 0 | } |
48 | | |
49 | | /// Big endian unsigned integer parser |
50 | | struct BeUint<Uint, E> { |
51 | | bound: usize, |
52 | | e: PhantomData<E>, |
53 | | u: PhantomData<Uint>, |
54 | | } |
55 | | |
56 | | impl<I, Uint, E: ParseError<I>> Parser<I> for BeUint<Uint, E> |
57 | | where |
58 | | I: Input<Item = u8>, |
59 | | Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>, |
60 | | { |
61 | | type Output = Uint; |
62 | | type Error = E; |
63 | | |
64 | | #[inline(always)] |
65 | 0 | fn process<OM: crate::OutputMode>( |
66 | 0 | &mut self, |
67 | 0 | input: I, |
68 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
69 | 0 | if input.input_len() < self.bound { |
70 | 0 | if OM::Incomplete::is_streaming() { |
71 | 0 | Err(Err::Incomplete(Needed::new(self.bound - input.input_len()))) |
72 | | } else { |
73 | 0 | Err(Err::Error(OM::Error::bind(|| { |
74 | 0 | make_error(input, ErrorKind::Eof) |
75 | 0 | }))) |
76 | | } |
77 | | } else { |
78 | 0 | let res = OM::Output::bind(|| { |
79 | 0 | let mut res = Uint::default(); |
80 | 0 |
|
81 | 0 | // special case to avoid shift a byte with overflow |
82 | 0 | if self.bound > 1 { |
83 | 0 | for byte in input.iter_elements().take(self.bound) { |
84 | 0 | res = (res << 8) + byte.into(); |
85 | 0 | } |
86 | | } else { |
87 | 0 | for byte in input.iter_elements().take(self.bound) { |
88 | 0 | res = byte.into(); |
89 | 0 | } |
90 | | } |
91 | | |
92 | 0 | res |
93 | 0 | }); |
94 | 0 |
|
95 | 0 | Ok((input.take_from(self.bound), res)) |
96 | | } |
97 | 0 | } |
98 | | } |
99 | | |
100 | | /// Recognizes an unsigned 1 byte integer. |
101 | | /// |
102 | | /// ```rust |
103 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
104 | | /// use nom::number::be_u8; |
105 | | /// |
106 | | /// let parser = |s| { |
107 | | /// be_u8::<_, (_, ErrorKind)>().parse(s) |
108 | | /// }; |
109 | | /// |
110 | | /// assert_eq!(parser(&b"\x00\x01abcd"[..]), Ok((&b"\x01abcd"[..], 0x00))); |
111 | | /// assert_eq!(parser(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
112 | | /// ``` |
113 | | #[inline] |
114 | 0 | pub fn be_u8<I, E: ParseError<I>>() -> impl Parser<I, Output = u8, Error = E> |
115 | 0 | where |
116 | 0 | I: Input<Item = u8>, |
117 | 0 | { |
118 | 0 | be_uint(1) |
119 | 0 | } |
120 | | |
121 | | /// Recognizes a big endian unsigned 2 bytes integer. |
122 | | /// |
123 | | /// ```rust |
124 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
125 | | /// use nom::number::be_u16; |
126 | | /// |
127 | | /// let parser = |s| { |
128 | | /// be_u16::<_, (_, ErrorKind)>().parse(s) |
129 | | /// }; |
130 | | /// |
131 | | /// assert_eq!(parser(&b"\x00\x01abcd"[..]), Ok((&b"abcd"[..], 0x0001))); |
132 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
133 | | /// ``` |
134 | | #[inline] |
135 | 0 | pub fn be_u16<I, E: ParseError<I>>() -> impl Parser<I, Output = u16, Error = E> |
136 | 0 | where |
137 | 0 | I: Input<Item = u8>, |
138 | 0 | { |
139 | 0 | be_uint(2) |
140 | 0 | } |
141 | | |
142 | | /// Recognizes a big endian unsigned 3 byte integer. |
143 | | /// |
144 | | /// ```rust |
145 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
146 | | /// use nom::number::be_u24; |
147 | | /// |
148 | | /// let parser = |s| { |
149 | | /// be_u24::<_, (_, ErrorKind)>().parse(s) |
150 | | /// }; |
151 | | /// |
152 | | /// assert_eq!(parser(&b"\x00\x01\x02abcd"[..]), Ok((&b"abcd"[..], 0x000102))); |
153 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
154 | | /// ``` |
155 | | #[inline] |
156 | 0 | pub fn be_u24<I, E: ParseError<I>>() -> impl Parser<I, Output = u32, Error = E> |
157 | 0 | where |
158 | 0 | I: Input<Item = u8>, |
159 | 0 | { |
160 | 0 | be_uint(3) |
161 | 0 | } |
162 | | |
163 | | /// Recognizes a big endian unsigned 4 bytes integer. |
164 | | /// |
165 | | /// ```rust |
166 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
167 | | /// use nom::number::be_u32; |
168 | | /// |
169 | | /// let parser = |s| { |
170 | | /// be_u32::<_, (_, ErrorKind)>().parse(s) |
171 | | /// }; |
172 | | /// |
173 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03abcd"[..]), Ok((&b"abcd"[..], 0x00010203))); |
174 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
175 | | /// ``` |
176 | | #[inline] |
177 | 0 | pub fn be_u32<I, E: ParseError<I>>() -> impl Parser<I, Output = u32, Error = E> |
178 | 0 | where |
179 | 0 | I: Input<Item = u8>, |
180 | 0 | { |
181 | 0 | be_uint(4) |
182 | 0 | } |
183 | | |
184 | | /// Recognizes a big endian unsigned 8 bytes integer. |
185 | | /// |
186 | | /// ```rust |
187 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
188 | | /// use nom::number::be_u64; |
189 | | /// |
190 | | /// let parser = |s| { |
191 | | /// be_u64::<_, (_, ErrorKind)>().parse(s) |
192 | | /// }; |
193 | | /// |
194 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..]), Ok((&b"abcd"[..], 0x0001020304050607))); |
195 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
196 | | /// ``` |
197 | | #[inline] |
198 | 0 | pub fn be_u64<I, E: ParseError<I>>() -> impl Parser<I, Output = u64, Error = E> |
199 | 0 | where |
200 | 0 | I: Input<Item = u8>, |
201 | 0 | { |
202 | 0 | be_uint(8) |
203 | 0 | } |
204 | | |
205 | | /// Recognizes a big endian unsigned 16 bytes integer. |
206 | | /// |
207 | | /// ```rust |
208 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
209 | | /// use nom::number::be_u128; |
210 | | /// |
211 | | /// let parser = |s| { |
212 | | /// be_u128::<_, (_, ErrorKind)>().parse(s) |
213 | | /// }; |
214 | | /// |
215 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..]), Ok((&b"abcd"[..], 0x00010203040506070809101112131415))); |
216 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
217 | | /// ``` |
218 | | #[inline] |
219 | 0 | pub fn be_u128<I, E: ParseError<I>>() -> impl Parser<I, Output = u128, Error = E> |
220 | 0 | where |
221 | 0 | I: Input<Item = u8>, |
222 | 0 | { |
223 | 0 | be_uint(16) |
224 | 0 | } |
225 | | |
226 | | /// Recognizes a signed 1 byte integer. |
227 | | /// |
228 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
229 | | /// ```rust |
230 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
231 | | /// use nom::number::be_i8; |
232 | | /// |
233 | | /// let mut parser = be_i8::<_, (_, ErrorKind)>(); |
234 | | /// |
235 | | /// assert_eq!(parser.parse(&b"\x00\x01abcd"[..]), Ok((&b"\x01abcd"[..], 0x00))); |
236 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
237 | | /// ``` |
238 | | #[inline] |
239 | 0 | pub fn be_i8<I, E: ParseError<I>>() -> impl Parser<I, Output = i8, Error = E> |
240 | 0 | where |
241 | 0 | I: Input<Item = u8>, |
242 | 0 | { |
243 | 0 | be_u8().map(|x| x as i8) |
244 | 0 | } |
245 | | |
246 | | /// Recognizes a big endian signed 2 bytes integer. |
247 | | /// |
248 | | /// ```rust |
249 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
250 | | /// use nom::number::be_i16; |
251 | | /// |
252 | | /// let mut parser = be_i16::<_, (_, ErrorKind)>(); |
253 | | /// |
254 | | /// assert_eq!(parser.parse(&b"\x00\x01abcd"[..]), Ok((&b"abcd"[..], 0x0001))); |
255 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(2)))); |
256 | | /// ``` |
257 | | #[inline] |
258 | 0 | pub fn be_i16<I, E: ParseError<I>>() -> impl Parser<I, Output = i16, Error = E> |
259 | 0 | where |
260 | 0 | I: Input<Item = u8>, |
261 | 0 | { |
262 | 0 | be_u16().map(|x| x as i16) |
263 | 0 | } |
264 | | |
265 | | /// Recognizes a big endian signed 3 bytes integer. |
266 | | /// |
267 | | /// ```rust |
268 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
269 | | /// use nom::number::be_i24; |
270 | | /// |
271 | | /// let mut parser = be_i24::<_, (_, ErrorKind)>(); |
272 | | /// |
273 | | /// assert_eq!(parser.parse(&b"\x00\x01\x02abcd"[..]), Ok((&b"abcd"[..], 0x000102))); |
274 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(3)))); |
275 | | /// ``` |
276 | | #[inline] |
277 | 0 | pub fn be_i24<I, E: ParseError<I>>() -> impl Parser<I, Output = i32, Error = E> |
278 | 0 | where |
279 | 0 | I: Input<Item = u8>, |
280 | 0 | { |
281 | 0 | // Same as the unsigned version but we need to sign-extend manually here |
282 | 0 | be_u24().map(|x| { |
283 | 0 | if x & 0x80_00_00 != 0 { |
284 | 0 | (x | 0xff_00_00_00) as i32 |
285 | | } else { |
286 | 0 | x as i32 |
287 | | } |
288 | 0 | }) |
289 | 0 | } |
290 | | |
291 | | /// Recognizes a big endian signed 4 bytes integer. |
292 | | /// |
293 | | /// ```rust |
294 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
295 | | /// use nom::number::be_i32; |
296 | | /// |
297 | | /// let mut parser = be_i32::<_, (_, ErrorKind)>(); |
298 | | /// |
299 | | /// assert_eq!(parser.parse(&b"\x00\x01\x02\x03abcd"[..]), Ok((&b"abcd"[..], 0x00010203))); |
300 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(4)))); |
301 | | /// ``` |
302 | | #[inline] |
303 | 0 | pub fn be_i32<I, E: ParseError<I>>() -> impl Parser<I, Output = i32, Error = E> |
304 | 0 | where |
305 | 0 | I: Input<Item = u8>, |
306 | 0 | { |
307 | 0 | be_u32().map(|x| x as i32) |
308 | 0 | } |
309 | | |
310 | | /// Recognizes a big endian signed 8 bytes integer. |
311 | | /// |
312 | | /// ```rust |
313 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
314 | | /// use nom::number::be_i64; |
315 | | /// |
316 | | /// let mut parser = be_i64::<_, (_, ErrorKind)>(); |
317 | | /// |
318 | | /// assert_eq!(parser.parse(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..]), Ok((&b"abcd"[..], 0x0001020304050607))); |
319 | | /// assert_eq!(parser.parse(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
320 | | /// ``` |
321 | | #[inline] |
322 | 0 | pub fn be_i64<I, E: ParseError<I>>() -> impl Parser<I, Output = i64, Error = E> |
323 | 0 | where |
324 | 0 | I: Input<Item = u8>, |
325 | 0 | { |
326 | 0 | be_u64().map(|x| x as i64) |
327 | 0 | } |
328 | | |
329 | | /// Recognizes a big endian signed 16 bytes integer. |
330 | | /// |
331 | | /// ```rust |
332 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
333 | | /// use nom::number::be_i128; |
334 | | /// |
335 | | /// let mut parser = be_i128::<_, (_, ErrorKind)>(); |
336 | | /// |
337 | | /// assert_eq!(parser.parse(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..]), Ok((&b"abcd"[..], 0x00010203040506070809101112131415))); |
338 | | /// assert_eq!(parser.parse(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
339 | | /// ``` |
340 | | #[inline] |
341 | 0 | pub fn be_i128<I, E: ParseError<I>>() -> impl Parser<I, Output = i128, Error = E> |
342 | 0 | where |
343 | 0 | I: Input<Item = u8>, |
344 | 0 | { |
345 | 0 | be_u128().map(|x| x as i128) |
346 | 0 | } |
347 | | |
348 | | /// creates a little endian unsigned integer parser |
349 | | /// |
350 | | /// * `bound`: the number of bytes that will be read |
351 | | /// * `Uint`: the output type |
352 | | #[inline] |
353 | 0 | fn le_uint<I, Uint, E: ParseError<I>>(bound: usize) -> impl Parser<I, Output = Uint, Error = E> |
354 | 0 | where |
355 | 0 | I: Input<Item = u8>, |
356 | 0 | Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>, |
357 | 0 | { |
358 | 0 | LeUint { |
359 | 0 | bound, |
360 | 0 | e: PhantomData, |
361 | 0 | u: PhantomData, |
362 | 0 | } |
363 | 0 | } |
364 | | |
365 | | /// Little endian unsigned integer parser |
366 | | struct LeUint<Uint, E> { |
367 | | bound: usize, |
368 | | e: PhantomData<E>, |
369 | | u: PhantomData<Uint>, |
370 | | } |
371 | | |
372 | | impl<I, Uint, E: ParseError<I>> Parser<I> for LeUint<Uint, E> |
373 | | where |
374 | | I: Input<Item = u8>, |
375 | | Uint: Default + Shl<u8, Output = Uint> + Add<Uint, Output = Uint> + From<u8>, |
376 | | { |
377 | | type Output = Uint; |
378 | | type Error = E; |
379 | | |
380 | | #[inline(always)] |
381 | 0 | fn process<OM: crate::OutputMode>( |
382 | 0 | &mut self, |
383 | 0 | input: I, |
384 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
385 | 0 | if input.input_len() < self.bound { |
386 | 0 | if OM::Incomplete::is_streaming() { |
387 | 0 | Err(Err::Incomplete(Needed::new(self.bound - input.input_len()))) |
388 | | } else { |
389 | 0 | Err(Err::Error(OM::Error::bind(|| { |
390 | 0 | make_error(input, ErrorKind::Eof) |
391 | 0 | }))) |
392 | | } |
393 | | } else { |
394 | 0 | let res = OM::Output::bind(|| { |
395 | 0 | let mut res = Uint::default(); |
396 | 0 | for (index, byte) in input.iter_elements().take(self.bound).enumerate() { |
397 | 0 | res = res + (Uint::from(byte) << (8 * index as u8)); |
398 | 0 | } |
399 | | |
400 | 0 | res |
401 | 0 | }); |
402 | 0 |
|
403 | 0 | Ok((input.take_from(self.bound), res)) |
404 | | } |
405 | 0 | } |
406 | | } |
407 | | |
408 | | /// Recognizes an unsigned 1 byte integer. |
409 | | /// |
410 | | /// ```rust |
411 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
412 | | /// use nom::number::le_u8; |
413 | | /// |
414 | | /// let mut parser = le_u8::<_, (_, ErrorKind)>(); |
415 | | /// |
416 | | /// assert_eq!(parser.parse(&b"\x00\x01abcd"[..]), Ok((&b"\x01abcd"[..], 0x00))); |
417 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
418 | | /// ``` |
419 | | #[inline] |
420 | 0 | pub fn le_u8<I, E: ParseError<I>>() -> impl Parser<I, Output = u8, Error = E> |
421 | 0 | where |
422 | 0 | I: Input<Item = u8>, |
423 | 0 | { |
424 | 0 | le_uint(1) |
425 | 0 | } |
426 | | |
427 | | /// Recognizes a little endian unsigned 2 bytes integer. |
428 | | /// |
429 | | /// |
430 | | /// ```rust |
431 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
432 | | /// use nom::number::le_u16; |
433 | | /// |
434 | | /// let parser = |s| { |
435 | | /// le_u16::<_, (_, ErrorKind)>().parse(s) |
436 | | /// }; |
437 | | /// |
438 | | /// assert_eq!(parser(&b"\x00\x01abcd"[..]), Ok((&b"abcd"[..], 0x0100))); |
439 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
440 | | /// ``` |
441 | | #[inline] |
442 | 0 | pub fn le_u16<I, E: ParseError<I>>() -> impl Parser<I, Output = u16, Error = E> |
443 | 0 | where |
444 | 0 | I: Input<Item = u8>, |
445 | 0 | { |
446 | 0 | le_uint(2) |
447 | 0 | } |
448 | | |
449 | | /// Recognizes a little endian unsigned 3 bytes integer. |
450 | | /// |
451 | | /// ```rust |
452 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
453 | | /// use nom::number::le_u24; |
454 | | /// |
455 | | /// let parser = |s| { |
456 | | /// le_u24::<_, (_, ErrorKind)>().parse(s) |
457 | | /// }; |
458 | | /// |
459 | | /// assert_eq!(parser(&b"\x00\x01\x02abcd"[..]), Ok((&b"abcd"[..], 0x020100))); |
460 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
461 | | /// ``` |
462 | | #[inline] |
463 | 0 | pub fn le_u24<I, E: ParseError<I>>() -> impl Parser<I, Output = u32, Error = E> |
464 | 0 | where |
465 | 0 | I: Input<Item = u8>, |
466 | 0 | { |
467 | 0 | le_uint(3) |
468 | 0 | } |
469 | | |
470 | | /// Recognizes a little endian unsigned 4 bytes integer. |
471 | | /// |
472 | | /// ```rust |
473 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
474 | | /// use nom::number::le_u32; |
475 | | /// |
476 | | /// let parser = |s| { |
477 | | /// le_u32::<_, (_, ErrorKind)>().parse(s) |
478 | | /// }; |
479 | | /// |
480 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03abcd"[..]), Ok((&b"abcd"[..], 0x03020100))); |
481 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
482 | | /// ``` |
483 | | #[inline] |
484 | 0 | pub fn le_u32<I, E: ParseError<I>>() -> impl Parser<I, Output = u32, Error = E> |
485 | 0 | where |
486 | 0 | I: Input<Item = u8>, |
487 | 0 | { |
488 | 0 | le_uint(4) |
489 | 0 | } |
490 | | |
491 | | /// Recognizes a little endian unsigned 8 bytes integer. |
492 | | /// |
493 | | /// ```rust |
494 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
495 | | /// use nom::number::le_u64; |
496 | | /// |
497 | | /// let parser = |s| { |
498 | | /// le_u64::<_, (_, ErrorKind)>().parse(s) |
499 | | /// }; |
500 | | /// |
501 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..]), Ok((&b"abcd"[..], 0x0706050403020100))); |
502 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
503 | | /// ``` |
504 | | #[inline] |
505 | 0 | pub fn le_u64<I, E: ParseError<I>>() -> impl Parser<I, Output = u64, Error = E> |
506 | 0 | where |
507 | 0 | I: Input<Item = u8>, |
508 | 0 | { |
509 | 0 | le_uint(8) |
510 | 0 | } |
511 | | |
512 | | /// Recognizes a little endian unsigned 16 bytes integer. |
513 | | /// |
514 | | /// ```rust |
515 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
516 | | /// use nom::number::le_u128; |
517 | | /// |
518 | | /// let mut parser = |s| { |
519 | | /// le_u128::<_, (_, ErrorKind)>().parse(s) |
520 | | /// }; |
521 | | /// |
522 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..]), Ok((&b"abcd"[..], 0x15141312111009080706050403020100))); |
523 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
524 | | /// ``` |
525 | | #[inline] |
526 | 0 | pub fn le_u128<I, E: ParseError<I>>() -> impl Parser<I, Output = u128, Error = E> |
527 | 0 | where |
528 | 0 | I: Input<Item = u8>, |
529 | 0 | { |
530 | 0 | le_uint(16) |
531 | 0 | } |
532 | | |
533 | | /// Recognizes a signed 1 byte integer. |
534 | | /// |
535 | | /// ```rust |
536 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
537 | | /// use nom::number::le_i8; |
538 | | /// |
539 | | /// let mut parser = le_i8::<_, (_, ErrorKind)>(); |
540 | | /// |
541 | | /// assert_eq!(parser.parse(&b"\x00\x01abcd"[..]), Ok((&b"\x01abcd"[..], 0x00))); |
542 | | /// assert_eq!(parser.parse(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
543 | | /// ``` |
544 | | #[inline] |
545 | 0 | pub fn le_i8<I, E: ParseError<I>>() -> impl Parser<I, Output = i8, Error = E> |
546 | 0 | where |
547 | 0 | I: Input<Item = u8>, |
548 | 0 | { |
549 | 0 | le_u8().map(|x| x as i8) |
550 | 0 | } |
551 | | |
552 | | /// Recognizes a little endian signed 2 bytes integer. |
553 | | /// |
554 | | /// ```rust |
555 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
556 | | /// use nom::number::le_i16; |
557 | | /// |
558 | | /// let parser = |s| { |
559 | | /// le_i16::<_, (_, ErrorKind)>().parse(s) |
560 | | /// }; |
561 | | /// |
562 | | /// assert_eq!(parser(&b"\x00\x01abcd"[..]), Ok((&b"abcd"[..], 0x0100))); |
563 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
564 | | /// ``` |
565 | | #[inline] |
566 | 0 | pub fn le_i16<I, E: ParseError<I>>() -> impl Parser<I, Output = i16, Error = E> |
567 | 0 | where |
568 | 0 | I: Input<Item = u8>, |
569 | 0 | { |
570 | 0 | le_u16().map(|x| x as i16) |
571 | 0 | } |
572 | | |
573 | | /// Recognizes a little endian signed 3 bytes integer. |
574 | | /// |
575 | | /// ```rust |
576 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
577 | | /// use nom::number::le_i24; |
578 | | /// |
579 | | /// let parser = |s| { |
580 | | /// le_i24::<_, (_, ErrorKind)>().parse(s) |
581 | | /// }; |
582 | | /// |
583 | | /// assert_eq!(parser(&b"\x00\x01\x02abcd"[..]), Ok((&b"abcd"[..], 0x020100))); |
584 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
585 | | /// ``` |
586 | | #[inline] |
587 | 0 | pub fn le_i24<I, E: ParseError<I>>() -> impl Parser<I, Output = i32, Error = E> |
588 | 0 | where |
589 | 0 | I: Input<Item = u8>, |
590 | 0 | { |
591 | 0 | // Same as the unsigned version but we need to sign-extend manually here |
592 | 0 | le_u24().map(|x| { |
593 | 0 | if x & 0x80_00_00 != 0 { |
594 | 0 | (x | 0xff_00_00_00) as i32 |
595 | | } else { |
596 | 0 | x as i32 |
597 | | } |
598 | 0 | }) |
599 | 0 | } |
600 | | |
601 | | /// Recognizes a little endian signed 4 bytes integer. |
602 | | /// |
603 | | /// ```rust |
604 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
605 | | /// use nom::number::le_i32; |
606 | | /// |
607 | | /// let parser = |s| { |
608 | | /// le_i32::<_, (_, ErrorKind)>().parse(s) |
609 | | /// }; |
610 | | /// |
611 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03abcd"[..]), Ok((&b"abcd"[..], 0x03020100))); |
612 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
613 | | /// ``` |
614 | | #[inline] |
615 | 0 | pub fn le_i32<I, E: ParseError<I>>() -> impl Parser<I, Output = i32, Error = E> |
616 | 0 | where |
617 | 0 | I: Input<Item = u8>, |
618 | 0 | { |
619 | 0 | le_u32().map(|x| x as i32) |
620 | 0 | } |
621 | | |
622 | | /// Recognizes a little endian signed 8 bytes integer. |
623 | | /// |
624 | | /// ```rust |
625 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
626 | | /// use nom::number::le_i64; |
627 | | /// |
628 | | /// let parser = |s| { |
629 | | /// le_i64::<_, (_, ErrorKind)>().parse(s) |
630 | | /// }; |
631 | | /// |
632 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcd"[..]), Ok((&b"abcd"[..], 0x0706050403020100))); |
633 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
634 | | /// ``` |
635 | | #[inline] |
636 | 0 | pub fn le_i64<I, E: ParseError<I>>() -> impl Parser<I, Output = i64, Error = E> |
637 | 0 | where |
638 | 0 | I: Input<Item = u8>, |
639 | 0 | { |
640 | 0 | le_u64().map(|x| x as i64) |
641 | 0 | } |
642 | | |
643 | | /// Recognizes a little endian signed 16 bytes integer. |
644 | | /// |
645 | | /// ```rust |
646 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
647 | | /// use nom::number::le_i128; |
648 | | /// |
649 | | /// let parser = |s| { |
650 | | /// le_i128::<_, (_, ErrorKind)>().parse(s) |
651 | | /// }; |
652 | | /// |
653 | | /// assert_eq!(parser(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15abcd"[..]), Ok((&b"abcd"[..], 0x15141312111009080706050403020100))); |
654 | | /// assert_eq!(parser(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
655 | | /// ``` |
656 | | #[inline] |
657 | 0 | pub fn le_i128<I, E: ParseError<I>>() -> impl Parser<I, Output = i128, Error = E> |
658 | 0 | where |
659 | 0 | I: Input<Item = u8>, |
660 | 0 | { |
661 | 0 | le_u128().map(|x| x as i128) |
662 | 0 | } |
663 | | |
664 | | /// Recognizes an unsigned 1 byte integer |
665 | | /// |
666 | | /// Note that endianness does not apply to 1 byte numbers. |
667 | | /// ```rust |
668 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
669 | | /// # use nom::Needed::Size; |
670 | | /// use nom::number::u8; |
671 | | /// |
672 | | /// let parser = |s| { |
673 | | /// u8::<_, (_, ErrorKind)>().parse(s) |
674 | | /// }; |
675 | | /// |
676 | | /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00))); |
677 | | /// assert_eq!(parser(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
678 | | /// ``` |
679 | | #[inline] |
680 | 0 | pub fn u8<I, E: ParseError<I>>() -> impl Parser<I, Output = u8, Error = E> |
681 | 0 | where |
682 | 0 | I: Input<Item = u8>, |
683 | 0 | { |
684 | 0 | be_u8() |
685 | 0 | } |
686 | | |
687 | | /// Recognizes an unsigned 2 bytes integer |
688 | | /// |
689 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian u16 integer, |
690 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian u16 integer. |
691 | | /// |
692 | | /// ```rust |
693 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
694 | | /// # use nom::Needed::Size; |
695 | | /// use nom::number::u16; |
696 | | /// |
697 | | /// let be_u16 = |s| { |
698 | | /// u16::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
699 | | /// }; |
700 | | /// |
701 | | /// assert_eq!(be_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003))); |
702 | | /// assert_eq!(be_u16(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
703 | | /// |
704 | | /// let le_u16 = |s| { |
705 | | /// u16::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
706 | | /// }; |
707 | | /// |
708 | | /// assert_eq!(le_u16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300))); |
709 | | /// assert_eq!(le_u16(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
710 | | /// ``` |
711 | | #[inline] |
712 | 0 | pub fn u16<I, E: ParseError<I>>( |
713 | 0 | endian: crate::number::Endianness, |
714 | 0 | ) -> impl Parser<I, Output = u16, Error = E> |
715 | 0 | where |
716 | 0 | I: Input<Item = u8>, |
717 | 0 | { |
718 | 0 | match endian { |
719 | 0 | crate::number::Endianness::Big => Either::Left(be_u16()), |
720 | 0 | crate::number::Endianness::Little => Either::Right(le_u16()), |
721 | | #[cfg(target_endian = "big")] |
722 | | crate::number::Endianness::Native => Either::Left(be_u16()), |
723 | | #[cfg(target_endian = "little")] |
724 | 0 | crate::number::Endianness::Native => Either::Right(le_u16()), |
725 | | } |
726 | 0 | } |
727 | | |
728 | | /// Recognizes an unsigned 3 byte integer |
729 | | /// |
730 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian u24 integer, |
731 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian u24 integer. |
732 | | /// ```rust |
733 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
734 | | /// # use nom::Needed::Size; |
735 | | /// use nom::number::u24; |
736 | | /// |
737 | | /// let be_u24 = |s| { |
738 | | /// u24::<_,(_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
739 | | /// }; |
740 | | /// |
741 | | /// assert_eq!(be_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305))); |
742 | | /// assert_eq!(be_u24(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
743 | | /// |
744 | | /// let le_u24 = |s| { |
745 | | /// u24::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
746 | | /// }; |
747 | | /// |
748 | | /// assert_eq!(le_u24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300))); |
749 | | /// assert_eq!(le_u24(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
750 | | /// ``` |
751 | | #[inline] |
752 | 0 | pub fn u24<I, E: ParseError<I>>( |
753 | 0 | endian: crate::number::Endianness, |
754 | 0 | ) -> impl Parser<I, Output = u32, Error = E> |
755 | 0 | where |
756 | 0 | I: Input<Item = u8>, |
757 | 0 | { |
758 | 0 | match endian { |
759 | 0 | crate::number::Endianness::Big => Either::Left(be_u24()), |
760 | 0 | crate::number::Endianness::Little => Either::Right(le_u24()), |
761 | | #[cfg(target_endian = "big")] |
762 | | crate::number::Endianness::Native => Either::Left(be_u24()), |
763 | | #[cfg(target_endian = "little")] |
764 | 0 | crate::number::Endianness::Native => Either::Right(le_u24()), |
765 | | } |
766 | 0 | } |
767 | | |
768 | | /// Recognizes an unsigned 4 byte integer |
769 | | /// |
770 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian u32 integer, |
771 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian u32 integer. |
772 | | /// ```rust |
773 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
774 | | /// # use nom::Needed::Size; |
775 | | /// use nom::number::u32; |
776 | | /// |
777 | | /// let be_u32 = |s| { |
778 | | /// u32::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
779 | | /// }; |
780 | | /// |
781 | | /// assert_eq!(be_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507))); |
782 | | /// assert_eq!(be_u32(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
783 | | /// |
784 | | /// let le_u32 = |s| { |
785 | | /// u32::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
786 | | /// }; |
787 | | /// |
788 | | /// assert_eq!(le_u32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300))); |
789 | | /// assert_eq!(le_u32(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
790 | | /// ``` |
791 | | #[inline] |
792 | 0 | pub fn u32<I, E: ParseError<I>>( |
793 | 0 | endian: crate::number::Endianness, |
794 | 0 | ) -> impl Parser<I, Output = u32, Error = E> |
795 | 0 | where |
796 | 0 | I: Input<Item = u8>, |
797 | 0 | { |
798 | 0 | match endian { |
799 | 0 | crate::number::Endianness::Big => Either::Left(be_u32()), |
800 | 0 | crate::number::Endianness::Little => Either::Right(le_u32()), |
801 | | #[cfg(target_endian = "big")] |
802 | | crate::number::Endianness::Native => Either::Left(be_u32()), |
803 | | #[cfg(target_endian = "little")] |
804 | 0 | crate::number::Endianness::Native => Either::Right(le_u32()), |
805 | | } |
806 | 0 | } |
807 | | |
808 | | /// Recognizes an unsigned 8 byte integer |
809 | | /// |
810 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian u64 integer, |
811 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian u64 integer. |
812 | | /// ```rust |
813 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
814 | | /// # use nom::Needed::Size; |
815 | | /// use nom::number::u64; |
816 | | /// |
817 | | /// let be_u64 = |s| { |
818 | | /// u64::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
819 | | /// }; |
820 | | /// |
821 | | /// assert_eq!(be_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607))); |
822 | | /// assert_eq!(be_u64(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
823 | | /// |
824 | | /// let le_u64 = |s| { |
825 | | /// u64::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
826 | | /// }; |
827 | | /// |
828 | | /// assert_eq!(le_u64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100))); |
829 | | /// assert_eq!(le_u64(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
830 | | /// ``` |
831 | | #[inline] |
832 | 0 | pub fn u64<I, E: ParseError<I>>( |
833 | 0 | endian: crate::number::Endianness, |
834 | 0 | ) -> impl Parser<I, Output = u64, Error = E> |
835 | 0 | where |
836 | 0 | I: Input<Item = u8>, |
837 | 0 | { |
838 | 0 | match endian { |
839 | 0 | crate::number::Endianness::Big => Either::Left(be_u64()), |
840 | 0 | crate::number::Endianness::Little => Either::Right(le_u64()), |
841 | | #[cfg(target_endian = "big")] |
842 | | crate::number::Endianness::Native => Either::Left(be_u64()), |
843 | | #[cfg(target_endian = "little")] |
844 | 0 | crate::number::Endianness::Native => Either::Right(le_u64()), |
845 | | } |
846 | 0 | } |
847 | | |
848 | | /// Recognizes an unsigned 16 byte integer |
849 | | /// |
850 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian u128 integer, |
851 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian u128 integer. |
852 | | /// ```rust |
853 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
854 | | /// # use nom::Needed::Size; |
855 | | /// use nom::number::u128; |
856 | | /// |
857 | | /// let be_u128 = |s| { |
858 | | /// u128::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
859 | | /// }; |
860 | | /// |
861 | | /// assert_eq!(be_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607))); |
862 | | /// assert_eq!(be_u128(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
863 | | /// |
864 | | /// let le_u128 = |s| { |
865 | | /// u128::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
866 | | /// }; |
867 | | /// |
868 | | /// assert_eq!(le_u128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100))); |
869 | | /// assert_eq!(le_u128(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
870 | | /// ``` |
871 | | #[inline] |
872 | 0 | pub fn u128<I, E: ParseError<I>>( |
873 | 0 | endian: crate::number::Endianness, |
874 | 0 | ) -> impl Parser<I, Output = u128, Error = E> |
875 | 0 | where |
876 | 0 | I: Input<Item = u8>, |
877 | 0 | { |
878 | 0 | match endian { |
879 | 0 | crate::number::Endianness::Big => Either::Left(be_u128()), |
880 | 0 | crate::number::Endianness::Little => Either::Right(le_u128()), |
881 | | #[cfg(target_endian = "big")] |
882 | | crate::number::Endianness::Native => Either::Left(be_u128()), |
883 | | #[cfg(target_endian = "little")] |
884 | 0 | crate::number::Endianness::Native => Either::Right(le_u128()), |
885 | | } |
886 | 0 | } |
887 | | |
888 | | /// Recognizes a signed 1 byte integer |
889 | | /// |
890 | | /// Note that endianness does not apply to 1 byte numbers. |
891 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
892 | | /// ```rust |
893 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
894 | | /// # use nom::Needed::Size; |
895 | | /// use nom::number::i8; |
896 | | /// |
897 | | /// let parser = |s| { |
898 | | /// i8::<_, (_, ErrorKind)>().parse(s) |
899 | | /// }; |
900 | | /// |
901 | | /// assert_eq!(parser(&b"\x00\x03abcefg"[..]), Ok((&b"\x03abcefg"[..], 0x00))); |
902 | | /// assert_eq!(parser(&b""[..]), Err(Err::Incomplete(Needed::new(1)))); |
903 | | /// ``` |
904 | | #[inline] |
905 | 0 | pub fn i8<I, E: ParseError<I>>() -> impl Parser<I, Output = i8, Error = E> |
906 | 0 | where |
907 | 0 | I: Input<Item = u8>, |
908 | 0 | { |
909 | 0 | u8().map(|x| x as i8) |
910 | 0 | } |
911 | | |
912 | | /// Recognizes a signed 2 byte integer |
913 | | /// |
914 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian i16 integer, |
915 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian i16 integer. |
916 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
917 | | /// ```rust |
918 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
919 | | /// # use nom::Needed::Size; |
920 | | /// use nom::number::i16; |
921 | | /// |
922 | | /// let be_i16 = |s| { |
923 | | /// i16::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
924 | | /// }; |
925 | | /// |
926 | | /// assert_eq!(be_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0003))); |
927 | | /// assert_eq!(be_i16(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
928 | | /// |
929 | | /// let le_i16 = |s| { |
930 | | /// i16::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
931 | | /// }; |
932 | | /// |
933 | | /// assert_eq!(le_i16(&b"\x00\x03abcefg"[..]), Ok((&b"abcefg"[..], 0x0300))); |
934 | | /// assert_eq!(le_i16(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(1)))); |
935 | | /// ``` |
936 | | #[inline] |
937 | 0 | pub fn i16<I, E: ParseError<I>>( |
938 | 0 | endian: crate::number::Endianness, |
939 | 0 | ) -> impl Parser<I, Output = i16, Error = E> |
940 | 0 | where |
941 | 0 | I: Input<Item = u8>, |
942 | 0 | { |
943 | 0 | match endian { |
944 | 0 | crate::number::Endianness::Big => Either::Left(be_i16()), |
945 | 0 | crate::number::Endianness::Little => Either::Right(le_i16()), |
946 | | #[cfg(target_endian = "big")] |
947 | | crate::number::Endianness::Native => Either::Left(be_i16()), |
948 | | #[cfg(target_endian = "little")] |
949 | 0 | crate::number::Endianness::Native => Either::Right(le_i16()), |
950 | | } |
951 | 0 | } |
952 | | |
953 | | /// Recognizes a signed 3 byte integer |
954 | | /// |
955 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian i24 integer, |
956 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian i24 integer. |
957 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
958 | | /// ```rust |
959 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
960 | | /// # use nom::Needed::Size; |
961 | | /// use nom::number::i24; |
962 | | /// |
963 | | /// let be_i24 = |s| { |
964 | | /// i24::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
965 | | /// }; |
966 | | /// |
967 | | /// assert_eq!(be_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x000305))); |
968 | | /// assert_eq!(be_i24(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
969 | | /// |
970 | | /// let le_i24 = |s| { |
971 | | /// i24::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
972 | | /// }; |
973 | | /// |
974 | | /// assert_eq!(le_i24(&b"\x00\x03\x05abcefg"[..]), Ok((&b"abcefg"[..], 0x050300))); |
975 | | /// assert_eq!(le_i24(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(2)))); |
976 | | /// ``` |
977 | | #[inline] |
978 | 0 | pub fn i24<I, E: ParseError<I>>( |
979 | 0 | endian: crate::number::Endianness, |
980 | 0 | ) -> impl Parser<I, Output = i32, Error = E> |
981 | 0 | where |
982 | 0 | I: Input<Item = u8>, |
983 | 0 | { |
984 | 0 | match endian { |
985 | 0 | crate::number::Endianness::Big => Either::Left(be_i24()), |
986 | 0 | crate::number::Endianness::Little => Either::Right(le_i24()), |
987 | | #[cfg(target_endian = "big")] |
988 | | crate::number::Endianness::Native => Either::Left(be_i24()), |
989 | | #[cfg(target_endian = "little")] |
990 | 0 | crate::number::Endianness::Native => Either::Right(le_i24()), |
991 | | } |
992 | 0 | } |
993 | | |
994 | | /// Recognizes a signed 4 byte integer |
995 | | /// |
996 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian i32 integer, |
997 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian i32 integer. |
998 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
999 | | /// ```rust |
1000 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1001 | | /// # use nom::Needed::Size; |
1002 | | /// use nom::number::i32; |
1003 | | /// |
1004 | | /// let be_i32 = |s| { |
1005 | | /// i32::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
1006 | | /// }; |
1007 | | /// |
1008 | | /// assert_eq!(be_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00030507))); |
1009 | | /// assert_eq!(be_i32(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
1010 | | /// |
1011 | | /// let le_i32 = |s| { |
1012 | | /// i32::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
1013 | | /// }; |
1014 | | /// |
1015 | | /// assert_eq!(le_i32(&b"\x00\x03\x05\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07050300))); |
1016 | | /// assert_eq!(le_i32(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(3)))); |
1017 | | /// ``` |
1018 | | #[inline] |
1019 | 0 | pub fn i32<I, E: ParseError<I>>( |
1020 | 0 | endian: crate::number::Endianness, |
1021 | 0 | ) -> impl Parser<I, Output = i32, Error = E> |
1022 | 0 | where |
1023 | 0 | I: Input<Item = u8>, |
1024 | 0 | { |
1025 | 0 | match endian { |
1026 | 0 | crate::number::Endianness::Big => Either::Left(be_i32()), |
1027 | 0 | crate::number::Endianness::Little => Either::Right(le_i32()), |
1028 | | #[cfg(target_endian = "big")] |
1029 | | crate::number::Endianness::Native => Either::Left(be_i32()), |
1030 | | #[cfg(target_endian = "little")] |
1031 | 0 | crate::number::Endianness::Native => Either::Right(le_i32()), |
1032 | | } |
1033 | 0 | } |
1034 | | |
1035 | | /// Recognizes a signed 8 byte integer |
1036 | | /// |
1037 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian i64 integer, |
1038 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian i64 integer. |
1039 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1040 | | /// ```rust |
1041 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1042 | | /// # use nom::Needed::Size; |
1043 | | /// use nom::number::i64; |
1044 | | /// |
1045 | | /// let be_i64 = |s| { |
1046 | | /// i64::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
1047 | | /// }; |
1048 | | /// |
1049 | | /// assert_eq!(be_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0001020304050607))); |
1050 | | /// assert_eq!(be_i64(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
1051 | | /// |
1052 | | /// let le_i64 = |s| { |
1053 | | /// i64::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
1054 | | /// }; |
1055 | | /// |
1056 | | /// assert_eq!(le_i64(&b"\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x0706050403020100))); |
1057 | | /// assert_eq!(le_i64(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(7)))); |
1058 | | /// ``` |
1059 | | #[inline] |
1060 | 0 | pub fn i64<I, E: ParseError<I>>( |
1061 | 0 | endian: crate::number::Endianness, |
1062 | 0 | ) -> impl Parser<I, Output = i64, Error = E> |
1063 | 0 | where |
1064 | 0 | I: Input<Item = u8>, |
1065 | 0 | { |
1066 | 0 | match endian { |
1067 | 0 | crate::number::Endianness::Big => Either::Left(be_i64()), |
1068 | 0 | crate::number::Endianness::Little => Either::Right(le_i64()), |
1069 | | #[cfg(target_endian = "big")] |
1070 | | crate::number::Endianness::Native => Either::Left(be_i64()), |
1071 | | #[cfg(target_endian = "little")] |
1072 | 0 | crate::number::Endianness::Native => Either::Right(le_i64()), |
1073 | | } |
1074 | 0 | } |
1075 | | |
1076 | | /// Recognizes a signed 16 byte integer |
1077 | | /// |
1078 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian i128 integer, |
1079 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian i128 integer. |
1080 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1081 | | /// ```rust |
1082 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1083 | | /// # use nom::Needed::Size; |
1084 | | /// use nom::number::i128; |
1085 | | /// |
1086 | | /// let be_i128 = |s| { |
1087 | | /// i128::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
1088 | | /// }; |
1089 | | /// |
1090 | | /// assert_eq!(be_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x00010203040506070001020304050607))); |
1091 | | /// assert_eq!(be_i128(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
1092 | | /// |
1093 | | /// let le_i128 = |s| { |
1094 | | /// i128::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
1095 | | /// }; |
1096 | | /// |
1097 | | /// assert_eq!(le_i128(&b"\x00\x01\x02\x03\x04\x05\x06\x07\x00\x01\x02\x03\x04\x05\x06\x07abcefg"[..]), Ok((&b"abcefg"[..], 0x07060504030201000706050403020100))); |
1098 | | /// assert_eq!(le_i128(&b"\x01"[..]), Err(Err::Incomplete(Needed::new(15)))); |
1099 | | /// ``` |
1100 | | #[inline] |
1101 | 0 | pub fn i128<I, E: ParseError<I>>( |
1102 | 0 | endian: crate::number::Endianness, |
1103 | 0 | ) -> impl Parser<I, Output = i128, Error = E> |
1104 | 0 | where |
1105 | 0 | I: Input<Item = u8>, |
1106 | 0 | { |
1107 | 0 | match endian { |
1108 | 0 | crate::number::Endianness::Big => Either::Left(be_i128()), |
1109 | 0 | crate::number::Endianness::Little => Either::Right(le_i128()), |
1110 | | #[cfg(target_endian = "big")] |
1111 | | crate::number::Endianness::Native => Either::Left(be_i128()), |
1112 | | #[cfg(target_endian = "little")] |
1113 | 0 | crate::number::Endianness::Native => Either::Right(le_i128()), |
1114 | | } |
1115 | 0 | } |
1116 | | |
1117 | | /// Recognizes a big endian 4 bytes floating point number. |
1118 | | /// |
1119 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1120 | | /// ```rust |
1121 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1122 | | /// use nom::number::be_f32; |
1123 | | /// |
1124 | | /// let parser = |s| { |
1125 | | /// be_f32::<_, (_, ErrorKind)>().parse(s) |
1126 | | /// }; |
1127 | | /// |
1128 | | /// assert_eq!(parser(&[0x40, 0x29, 0x00, 0x00][..]), Ok((&b""[..], 2.640625))); |
1129 | | /// assert_eq!(parser(&[0x01][..]), Err(Err::Incomplete(Needed::new(3)))); |
1130 | | /// ``` |
1131 | | #[inline] |
1132 | 0 | pub fn be_f32<I, E: ParseError<I>>() -> impl Parser<I, Output = f32, Error = E> |
1133 | 0 | where |
1134 | 0 | I: Input<Item = u8>, |
1135 | 0 | { |
1136 | 0 | be_u32().map(f32::from_bits) |
1137 | 0 | } |
1138 | | |
1139 | | /// Recognizes a big endian 8 bytes floating point number. |
1140 | | /// |
1141 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1142 | | /// ```rust |
1143 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1144 | | /// use nom::number::be_f64; |
1145 | | /// |
1146 | | /// let parser = |s| { |
1147 | | /// be_f64::<_, (_, ErrorKind)>().parse(s) |
1148 | | /// }; |
1149 | | /// |
1150 | | /// assert_eq!(parser(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5))); |
1151 | | /// assert_eq!(parser(&[0x01][..]), Err(Err::Incomplete(Needed::new(7)))); |
1152 | | /// ``` |
1153 | | #[inline] |
1154 | 0 | pub fn be_f64<I, E: ParseError<I>>() -> impl Parser<I, Output = f64, Error = E> |
1155 | 0 | where |
1156 | 0 | I: Input<Item = u8>, |
1157 | 0 | { |
1158 | 0 | be_u64().map(f64::from_bits) |
1159 | 0 | } |
1160 | | |
1161 | | /// Recognizes a little endian 4 bytes floating point number. |
1162 | | /// |
1163 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1164 | | /// ```rust |
1165 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1166 | | /// use nom::number::le_f32; |
1167 | | /// |
1168 | | /// let parser = |s| { |
1169 | | /// le_f32::<_, (_, ErrorKind)>().parse(s) |
1170 | | /// }; |
1171 | | /// |
1172 | | /// assert_eq!(parser(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5))); |
1173 | | /// assert_eq!(parser(&[0x01][..]), Err(Err::Incomplete(Needed::new(3)))); |
1174 | | /// ``` |
1175 | | #[inline] |
1176 | 0 | pub fn le_f32<I, E: ParseError<I>>() -> impl Parser<I, Output = f32, Error = E> |
1177 | 0 | where |
1178 | 0 | I: Input<Item = u8>, |
1179 | 0 | { |
1180 | 0 | le_u32().map(f32::from_bits) |
1181 | 0 | } |
1182 | | |
1183 | | /// Recognizes a little endian 8 bytes floating point number. |
1184 | | /// |
1185 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1186 | | /// ```rust |
1187 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1188 | | /// use nom::number::le_f64; |
1189 | | /// |
1190 | | /// let parser = |s| { |
1191 | | /// le_f64::<_, (_, ErrorKind)>().parse(s) |
1192 | | /// }; |
1193 | | /// |
1194 | | /// assert_eq!(parser(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 3145728.0))); |
1195 | | /// assert_eq!(parser(&[0x01][..]), Err(Err::Incomplete(Needed::new(7)))); |
1196 | | /// ``` |
1197 | | #[inline] |
1198 | 0 | pub fn le_f64<I, E: ParseError<I>>() -> impl Parser<I, Output = f64, Error = E> |
1199 | 0 | where |
1200 | 0 | I: Input<Item = u8>, |
1201 | 0 | { |
1202 | 0 | le_u64().map(f64::from_bits) |
1203 | 0 | } |
1204 | | |
1205 | | /// Recognizes a 4 byte floating point number |
1206 | | /// |
1207 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian f32 float, |
1208 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian f32 float. |
1209 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1210 | | /// ```rust |
1211 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1212 | | /// # use nom::Needed::Size; |
1213 | | /// use nom::number::f32; |
1214 | | /// |
1215 | | /// let be_f32 = |s| { |
1216 | | /// f32::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
1217 | | /// }; |
1218 | | /// |
1219 | | /// assert_eq!(be_f32(&[0x41, 0x48, 0x00, 0x00][..]), Ok((&b""[..], 12.5))); |
1220 | | /// assert_eq!(be_f32(&b"abc"[..]), Err(Err::Incomplete(Needed::new(1)))); |
1221 | | /// |
1222 | | /// let le_f32 = |s| { |
1223 | | /// f32::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
1224 | | /// }; |
1225 | | /// |
1226 | | /// assert_eq!(le_f32(&[0x00, 0x00, 0x48, 0x41][..]), Ok((&b""[..], 12.5))); |
1227 | | /// assert_eq!(le_f32(&b"abc"[..]), Err(Err::Incomplete(Needed::new(1)))); |
1228 | | /// ``` |
1229 | | #[inline] |
1230 | 0 | pub fn f32<I, E: ParseError<I>>( |
1231 | 0 | endian: crate::number::Endianness, |
1232 | 0 | ) -> impl Parser<I, Output = f32, Error = E> |
1233 | 0 | where |
1234 | 0 | I: Input<Item = u8>, |
1235 | 0 | { |
1236 | 0 | match endian { |
1237 | 0 | crate::number::Endianness::Big => Either::Left(be_f32()), |
1238 | 0 | crate::number::Endianness::Little => Either::Right(le_f32()), |
1239 | | #[cfg(target_endian = "big")] |
1240 | | crate::number::Endianness::Native => Either::Left(be_f32()), |
1241 | | #[cfg(target_endian = "little")] |
1242 | 0 | crate::number::Endianness::Native => Either::Right(le_f32()), |
1243 | | } |
1244 | 0 | } |
1245 | | |
1246 | | /// Recognizes an 8 byte floating point number |
1247 | | /// |
1248 | | /// If the parameter is `nom::number::Endianness::Big`, parse a big endian f64 float, |
1249 | | /// otherwise if `nom::number::Endianness::Little` parse a little endian f64 float. |
1250 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if there is not enough data. |
1251 | | /// ```rust |
1252 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1253 | | /// # use nom::Needed::Size; |
1254 | | /// use nom::number::f64; |
1255 | | /// |
1256 | | /// let be_f64 = |s| { |
1257 | | /// f64::<_, (_, ErrorKind)>(nom::number::Endianness::Big).parse(s) |
1258 | | /// }; |
1259 | | /// |
1260 | | /// assert_eq!(be_f64(&[0x40, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00][..]), Ok((&b""[..], 12.5))); |
1261 | | /// assert_eq!(be_f64(&b"abc"[..]), Err(Err::Incomplete(Needed::new(5)))); |
1262 | | /// |
1263 | | /// let le_f64 = |s| { |
1264 | | /// f64::<_, (_, ErrorKind)>(nom::number::Endianness::Little).parse(s) |
1265 | | /// }; |
1266 | | /// |
1267 | | /// assert_eq!(le_f64(&[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x40][..]), Ok((&b""[..], 12.5))); |
1268 | | /// assert_eq!(le_f64(&b"abc"[..]), Err(Err::Incomplete(Needed::new(5)))); |
1269 | | /// ``` |
1270 | | #[inline] |
1271 | 0 | pub fn f64<I, E: ParseError<I>>( |
1272 | 0 | endian: crate::number::Endianness, |
1273 | 0 | ) -> impl Parser<I, Output = f64, Error = E> |
1274 | 0 | where |
1275 | 0 | I: Input<Item = u8>, |
1276 | 0 | { |
1277 | 0 | match endian { |
1278 | 0 | crate::number::Endianness::Big => Either::Left(be_f64()), |
1279 | 0 | crate::number::Endianness::Little => Either::Right(le_f64()), |
1280 | | #[cfg(target_endian = "big")] |
1281 | | crate::number::Endianness::Native => Either::Left(be_f64()), |
1282 | | #[cfg(target_endian = "little")] |
1283 | 0 | crate::number::Endianness::Native => Either::Right(le_f64()), |
1284 | | } |
1285 | 0 | } |
1286 | | |
1287 | | /// Recognizes a floating point number in text format and returns the corresponding part of the input. |
1288 | | /// |
1289 | | /// *Streaming version*: Will return `Err(nom::Err::Incomplete(_))` if it reaches the end of input. |
1290 | | /// |
1291 | | /// ```rust |
1292 | | /// # use nom::{Err, error::ErrorKind, Needed, Parser}; |
1293 | | /// use nom::number::recognize_float; |
1294 | | /// |
1295 | | /// let parser = |s| { |
1296 | | /// recognize_float().parse(s) |
1297 | | /// }; |
1298 | | /// |
1299 | | /// assert_eq!(parser("11e-1;"), Ok((";", "11e-1"))); |
1300 | | /// assert_eq!(parser("123E-02;"), Ok((";", "123E-02"))); |
1301 | | /// assert_eq!(parser("123K-01"), Ok(("K-01", "123"))); |
1302 | | /// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Char)))); |
1303 | | /// ``` |
1304 | | #[rustfmt::skip] |
1305 | 0 | pub fn recognize_float<T, E:ParseError<T>>() -> impl Parser<T, Output=T,Error= E> |
1306 | 0 | where |
1307 | 0 | T: Clone + Offset, |
1308 | 0 | T: Input, |
1309 | 0 | <T as Input>::Item: AsChar, |
1310 | 0 | { |
1311 | 0 | recognize(( |
1312 | 0 | opt(alt((char('+'), char('-')))), |
1313 | 0 | alt(( |
1314 | 0 | map((digit1(), opt(pair(char('.'), opt(digit1())))), |_| ()), |
1315 | 0 | map((char('.'), digit1()), |_| ()) |
1316 | 0 | )), |
1317 | 0 | opt(( |
1318 | 0 | alt((char('e'), char('E'))), |
1319 | 0 | opt(alt((char('+'), char('-')))), |
1320 | 0 | cut(digit1()) |
1321 | 0 | )) |
1322 | 0 | )) |
1323 | 0 | } |
1324 | | |
1325 | | /// float number text parser that also recognizes "nan", "infinity" and "inf" (case insensitive) |
1326 | 0 | pub fn recognize_float_or_exceptions<T, E: ParseError<T>>() -> impl Parser<T, Output = T, Error = E> |
1327 | 0 | where |
1328 | 0 | T: Clone + Offset, |
1329 | 0 | T: Input + Compare<&'static str>, |
1330 | 0 | <T as Input>::Item: AsChar, |
1331 | 0 | { |
1332 | 0 | alt(( |
1333 | 0 | recognize_float::<_, E>(), |
1334 | 0 | |i: T| { |
1335 | 0 | crate::bytes::streaming::tag_no_case::<_, _, E>("nan")(i.clone()) |
1336 | 0 | .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float))) |
1337 | 0 | }, |
1338 | 0 | |i: T| { |
1339 | 0 | crate::bytes::streaming::tag_no_case::<_, _, E>("infinity")(i.clone()) |
1340 | 0 | .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float))) |
1341 | 0 | }, |
1342 | 0 | |i: T| { |
1343 | 0 | crate::bytes::streaming::tag_no_case::<_, _, E>("inf")(i.clone()) |
1344 | 0 | .map_err(|_| crate::Err::Error(E::from_error_kind(i, ErrorKind::Float))) |
1345 | 0 | }, |
1346 | 0 | )) |
1347 | 0 | } |
1348 | | |
1349 | | /// single precision floating point number parser from text |
1350 | 0 | pub fn float<T, E: ParseError<T>>() -> impl Parser<T, Output = f32, Error = E> |
1351 | 0 | where |
1352 | 0 | T: Clone + Offset, |
1353 | 0 | T: Input + crate::traits::ParseTo<f32> + Compare<&'static str>, |
1354 | 0 | <T as Input>::Item: AsChar + Clone, |
1355 | 0 | T: AsBytes, |
1356 | 0 | T: for<'a> Compare<&'a [u8]>, |
1357 | 0 | { |
1358 | 0 | Float { |
1359 | 0 | o: PhantomData, |
1360 | 0 | e: PhantomData, |
1361 | 0 | } |
1362 | 0 | } |
1363 | | |
1364 | | /// double precision floating point number parser from text |
1365 | 0 | pub fn double<T, E: ParseError<T>>() -> impl Parser<T, Output = f64, Error = E> |
1366 | 0 | where |
1367 | 0 | T: Clone + Offset, |
1368 | 0 | T: Input + crate::traits::ParseTo<f64> + Compare<&'static str>, |
1369 | 0 | <T as Input>::Item: AsChar + Clone, |
1370 | 0 | T: AsBytes, |
1371 | 0 | T: for<'a> Compare<&'a [u8]>, |
1372 | 0 | { |
1373 | 0 | Float { |
1374 | 0 | o: PhantomData, |
1375 | 0 | e: PhantomData, |
1376 | 0 | } |
1377 | 0 | } |
1378 | | |
1379 | | /// f64 parser from text |
1380 | | struct Float<O, E> { |
1381 | | o: PhantomData<O>, |
1382 | | e: PhantomData<E>, |
1383 | | } |
1384 | | |
1385 | | impl<I, O, E: ParseError<I>> Parser<I> for Float<O, E> |
1386 | | where |
1387 | | I: Clone + Offset, |
1388 | | I: Input + crate::traits::ParseTo<O> + Compare<&'static str>, |
1389 | | <I as Input>::Item: AsChar + Clone, |
1390 | | I: AsBytes, |
1391 | | I: for<'a> Compare<&'a [u8]>, |
1392 | | { |
1393 | | type Output = O; |
1394 | | type Error = E; |
1395 | | |
1396 | 0 | fn process<OM: crate::OutputMode>( |
1397 | 0 | &mut self, |
1398 | 0 | input: I, |
1399 | 0 | ) -> crate::PResult<OM, I, Self::Output, Self::Error> { |
1400 | 0 | let (i, s) = |
1401 | 0 | recognize_float_or_exceptions().process::<OutputM<Emit, OM::Error, OM::Incomplete>>(input)?; |
1402 | | |
1403 | 0 | match s.parse_to() { |
1404 | 0 | Some(f) => Ok((i, OM::Output::bind(|| f))), |
1405 | 0 | None => Err(crate::Err::Error(OM::Error::bind(|| { |
1406 | 0 | E::from_error_kind(i, crate::error::ErrorKind::Float) |
1407 | 0 | }))), |
1408 | | } |
1409 | 0 | } |
1410 | | } |
1411 | | |
1412 | | #[cfg(test)] |
1413 | | #[cfg(feature = "std")] |
1414 | | mod tests { |
1415 | | use super::*; |
1416 | | use crate::error::ErrorKind; |
1417 | | use crate::internal::Err; |
1418 | | |
1419 | | macro_rules! assert_parse( |
1420 | | ($left: expr, $right: expr) => { |
1421 | | let res: $crate::IResult<_, _, (_, ErrorKind)> = $left; |
1422 | | assert_eq!(res, $right); |
1423 | | }; |
1424 | | ); |
1425 | | |
1426 | | #[test] |
1427 | | fn float_test() { |
1428 | | let mut test_cases = vec![ |
1429 | | "+3.14", |
1430 | | "3.14", |
1431 | | "-3.14", |
1432 | | "0", |
1433 | | "0.0", |
1434 | | "1.", |
1435 | | ".789", |
1436 | | "-.5", |
1437 | | "1e7", |
1438 | | "-1E-7", |
1439 | | ".3e-2", |
1440 | | "1.e4", |
1441 | | "1.2e4", |
1442 | | "12.34", |
1443 | | "-1.234E-12", |
1444 | | "-1.234e-12", |
1445 | | "0.00000000000000000087", |
1446 | | ]; |
1447 | | |
1448 | | for test in test_cases.drain(..) { |
1449 | | let expected32 = str::parse::<f32>(test).unwrap(); |
1450 | | let expected64 = str::parse::<f64>(test).unwrap(); |
1451 | | |
1452 | | println!("now parsing: {} -> {}", test, expected32); |
1453 | | |
1454 | | assert_parse!(recognize_float().parse_complete(test), Ok(("", test))); |
1455 | | |
1456 | | /*assert_parse!(float(test.as_bytes()), Ok((&b""[..], expected32))); |
1457 | | assert_parse!(float(test), Ok(("", expected32))); |
1458 | | */ |
1459 | | |
1460 | | assert_parse!( |
1461 | | double().parse_complete(test.as_bytes()), |
1462 | | Ok((&b""[..], expected64)) |
1463 | | ); |
1464 | | assert_parse!(double().parse_complete(test), Ok(("", expected64))); |
1465 | | } |
1466 | | |
1467 | | let remaining_exponent = "-1.234E-"; |
1468 | | assert_parse!( |
1469 | | recognize_float().parse_complete(remaining_exponent), |
1470 | | Err(Err::Failure(("", ErrorKind::Digit))) |
1471 | | ); |
1472 | | |
1473 | | /*let (_i, nan) = float::<_, ()>("NaN").unwrap(); |
1474 | | assert!(nan.is_nan()); |
1475 | | |
1476 | | let (_i, inf) = float::<_, ()>("inf").unwrap(); |
1477 | | assert!(inf.is_infinite()); |
1478 | | let (i, inf) = float::<_, ()>("infinity").unwrap(); |
1479 | | assert!(inf.is_infinite()); |
1480 | | assert!(i.is_empty());*/ |
1481 | | } |
1482 | | } |