nom8/character/mod.rs
1//! Character specific parsers and combinators
2//!
3//! Functions recognizing specific characters
4
5#![allow(deprecated)] // will just become `pub(crate)` later
6
7pub mod complete;
8pub mod streaming;
9#[cfg(test)]
10mod tests;
11
12use crate::error::ParseError;
13use crate::input::Compare;
14use crate::input::{
15 AsBytes, AsChar, InputIsStreaming, InputIter, InputLength, InputTake, InputTakeAtPosition,
16 IntoOutput, Offset, ParseTo, Slice,
17};
18use crate::lib::std::ops::{Range, RangeFrom, RangeTo};
19use crate::IResult;
20
21/// Recognizes the string "\r\n".
22///
23/// *Complete version*: Will return an error if there's not enough input data.
24///
25/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
26///
27/// # Example
28///
29/// ```
30/// # use nom8::{Err, error::{Error, ErrorKind}, IResult};
31/// # use nom8::character::crlf;
32/// fn parser(input: &str) -> IResult<&str, &str> {
33/// crlf(input)
34/// }
35///
36/// assert_eq!(parser("\r\nc"), Ok(("c", "\r\n")));
37/// assert_eq!(parser("ab\r\nc"), Err(Err::Error(Error::new("ab\r\nc", ErrorKind::CrLf))));
38/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::CrLf))));
39/// ```
40///
41/// ```
42/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
43/// # use nom8::input::Streaming;
44/// # use nom8::character::crlf;
45/// assert_eq!(crlf::<_, (_, ErrorKind), true>(Streaming("\r\nc")), Ok((Streaming("c"), "\r\n")));
46/// assert_eq!(crlf::<_, (_, ErrorKind), true>(Streaming("ab\r\nc")), Err(Err::Error((Streaming("ab\r\nc"), ErrorKind::CrLf))));
47/// assert_eq!(crlf::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(2))));
48/// ```
49#[inline(always)]
50pub fn crlf<T, E: ParseError<T>, const STREAMING: bool>(
51 input: T,
52) -> IResult<T, <T as IntoOutput>::Output, E>
53where
54 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
55 T: InputIter + InputIsStreaming<STREAMING>,
56 T: IntoOutput,
57 T: Compare<&'static str>,
58{
59 if STREAMING {
60 streaming::crlf(input)
61 } else {
62 complete::crlf(input)
63 }
64}
65
66/// Recognizes a string of any char except '\r\n' or '\n'.
67///
68/// *Complete version*: Will return an error if there's not enough input data.
69///
70/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
71///
72/// # Example
73///
74/// ```
75/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
76/// # use nom8::character::not_line_ending;
77/// fn parser(input: &str) -> IResult<&str, &str> {
78/// not_line_ending(input)
79/// }
80///
81/// assert_eq!(parser("ab\r\nc"), Ok(("\r\nc", "ab")));
82/// assert_eq!(parser("ab\nc"), Ok(("\nc", "ab")));
83/// assert_eq!(parser("abc"), Ok(("", "abc")));
84/// assert_eq!(parser(""), Ok(("", "")));
85/// assert_eq!(parser("a\rb\nc"), Err(Err::Error(Error { input: "a\rb\nc", code: ErrorKind::Tag })));
86/// assert_eq!(parser("a\rbc"), Err(Err::Error(Error { input: "a\rbc", code: ErrorKind::Tag })));
87/// ```
88///
89/// ```
90/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
91/// # use nom8::input::Streaming;
92/// # use nom8::character::not_line_ending;
93/// assert_eq!(not_line_ending::<_, (_, ErrorKind), true>(Streaming("ab\r\nc")), Ok((Streaming("\r\nc"), "ab")));
94/// assert_eq!(not_line_ending::<_, (_, ErrorKind), true>(Streaming("abc")), Err(Err::Incomplete(Needed::Unknown)));
95/// assert_eq!(not_line_ending::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::Unknown)));
96/// assert_eq!(not_line_ending::<_, (_, ErrorKind), true>(Streaming("a\rb\nc")), Err(Err::Error((Streaming("a\rb\nc"), ErrorKind::Tag ))));
97/// assert_eq!(not_line_ending::<_, (_, ErrorKind), true>(Streaming("a\rbc")), Err(Err::Error((Streaming("a\rbc"), ErrorKind::Tag ))));
98/// ```
99#[inline(always)]
100pub fn not_line_ending<T, E: ParseError<T>, const STREAMING: bool>(
101 input: T,
102) -> IResult<T, <T as IntoOutput>::Output, E>
103where
104 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
105 T: InputIter + InputLength + InputIsStreaming<STREAMING>,
106 T: IntoOutput,
107 T: Compare<&'static str>,
108 <T as InputIter>::Item: AsChar,
109 <T as InputIter>::Item: AsChar,
110{
111 if STREAMING {
112 streaming::not_line_ending(input)
113 } else {
114 complete::not_line_ending(input)
115 }
116}
117
118/// Recognizes an end of line (both '\n' and '\r\n').
119///
120/// *Complete version*: Will return an error if there's not enough input data.
121///
122/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
123///
124/// # Example
125///
126/// ```
127/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
128/// # use nom8::character::line_ending;
129/// fn parser(input: &str) -> IResult<&str, &str> {
130/// line_ending(input)
131/// }
132///
133/// assert_eq!(parser("\r\nc"), Ok(("c", "\r\n")));
134/// assert_eq!(parser("ab\r\nc"), Err(Err::Error(Error::new("ab\r\nc", ErrorKind::CrLf))));
135/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::CrLf))));
136/// ```
137///
138/// ```
139/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
140/// # use nom8::input::Streaming;
141/// # use nom8::character::line_ending;
142/// assert_eq!(line_ending::<_, (_, ErrorKind), true>(Streaming("\r\nc")), Ok((Streaming("c"), "\r\n")));
143/// assert_eq!(line_ending::<_, (_, ErrorKind), true>(Streaming("ab\r\nc")), Err(Err::Error((Streaming("ab\r\nc"), ErrorKind::CrLf))));
144/// assert_eq!(line_ending::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
145/// ```
146#[inline(always)]
147pub fn line_ending<T, E: ParseError<T>, const STREAMING: bool>(
148 input: T,
149) -> IResult<T, <T as IntoOutput>::Output, E>
150where
151 T: Slice<Range<usize>> + Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
152 T: InputIter + InputLength + InputIsStreaming<STREAMING>,
153 T: IntoOutput,
154 T: Compare<&'static str>,
155{
156 if STREAMING {
157 streaming::line_ending(input)
158 } else {
159 complete::line_ending(input)
160 }
161}
162
163/// Matches a newline character '\n'.
164///
165/// *Complete version*: Will return an error if there's not enough input data.
166///
167/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
168///
169/// # Example
170///
171/// ```
172/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
173/// # use nom8::character::newline;
174/// fn parser(input: &str) -> IResult<&str, char> {
175/// newline(input)
176/// }
177///
178/// assert_eq!(parser("\nc"), Ok(("c", '\n')));
179/// assert_eq!(parser("\r\nc"), Err(Err::Error(Error::new("\r\nc", ErrorKind::Char))));
180/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Char))));
181/// ```
182///
183/// ```
184/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
185/// # use nom8::input::Streaming;
186/// # use nom8::character::newline;
187/// assert_eq!(newline::<_, (_, ErrorKind), true>(Streaming("\nc")), Ok((Streaming("c"), '\n')));
188/// assert_eq!(newline::<_, (_, ErrorKind), true>(Streaming("\r\nc")), Err(Err::Error((Streaming("\r\nc"), ErrorKind::Char))));
189/// assert_eq!(newline::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
190/// ```
191#[inline(always)]
192pub fn newline<I, Error: ParseError<I>, const STREAMING: bool>(input: I) -> IResult<I, char, Error>
193where
194 I: Slice<RangeFrom<usize>> + InputIter + InputLength + InputIsStreaming<STREAMING>,
195 <I as InputIter>::Item: AsChar,
196{
197 if STREAMING {
198 streaming::newline(input)
199 } else {
200 complete::newline(input)
201 }
202}
203
204/// Matches a tab character '\t'.
205///
206/// *Complete version*: Will return an error if there's not enough input data.
207///
208/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
209///
210/// # Example
211///
212/// ```
213/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
214/// # use nom8::character::tab;
215/// fn parser(input: &str) -> IResult<&str, char> {
216/// tab(input)
217/// }
218///
219/// assert_eq!(parser("\tc"), Ok(("c", '\t')));
220/// assert_eq!(parser("\r\nc"), Err(Err::Error(Error::new("\r\nc", ErrorKind::Char))));
221/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Char))));
222/// ```
223///
224/// ```
225/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
226/// # use nom8::input::Streaming;
227/// # use nom8::character::tab;
228/// assert_eq!(tab::<_, (_, ErrorKind), true>(Streaming("\tc")), Ok((Streaming("c"), '\t')));
229/// assert_eq!(tab::<_, (_, ErrorKind), true>(Streaming("\r\nc")), Err(Err::Error((Streaming("\r\nc"), ErrorKind::Char))));
230/// assert_eq!(tab::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
231/// ```
232#[inline(always)]
233pub fn tab<I, Error: ParseError<I>, const STREAMING: bool>(input: I) -> IResult<I, char, Error>
234where
235 I: Slice<RangeFrom<usize>> + InputIter + InputLength + InputIsStreaming<STREAMING>,
236 <I as InputIter>::Item: AsChar,
237{
238 if STREAMING {
239 streaming::tab(input)
240 } else {
241 complete::tab(input)
242 }
243}
244
245/// Recognizes zero or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
246///
247/// *Complete version*: Will return the whole input if no terminating token is found (a non
248/// alphabetic character).
249///
250/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
251/// or if no terminating token is found (a non alphabetic character).
252///
253/// # Example
254///
255/// ```
256/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
257/// # use nom8::character::alpha0;
258/// fn parser(input: &str) -> IResult<&str, &str> {
259/// alpha0(input)
260/// }
261///
262/// assert_eq!(parser("ab1c"), Ok(("1c", "ab")));
263/// assert_eq!(parser("1c"), Ok(("1c", "")));
264/// assert_eq!(parser(""), Ok(("", "")));
265/// ```
266///
267/// ```
268/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
269/// # use nom8::input::Streaming;
270/// # use nom8::character::alpha0;
271/// assert_eq!(alpha0::<_, (_, ErrorKind), true>(Streaming("ab1c")), Ok((Streaming("1c"), "ab")));
272/// assert_eq!(alpha0::<_, (_, ErrorKind), true>(Streaming("1c")), Ok((Streaming("1c"), "")));
273/// assert_eq!(alpha0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
274/// ```
275#[inline(always)]
276pub fn alpha0<T, E: ParseError<T>, const STREAMING: bool>(
277 input: T,
278) -> IResult<T, <T as IntoOutput>::Output, E>
279where
280 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
281 T: IntoOutput,
282 <T as InputTakeAtPosition>::Item: AsChar,
283{
284 if STREAMING {
285 streaming::alpha0(input)
286 } else {
287 complete::alpha0(input)
288 }
289}
290
291/// Recognizes one or more lowercase and uppercase ASCII alphabetic characters: a-z, A-Z
292///
293/// *Complete version*: Will return an error if there's not enough input data,
294/// or the whole input if no terminating token is found (a non alphabetic character).
295///
296/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
297/// or if no terminating token is found (a non alphabetic character).
298///
299/// # Example
300///
301/// ```
302/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
303/// # use nom8::character::alpha1;
304/// fn parser(input: &str) -> IResult<&str, &str> {
305/// alpha1(input)
306/// }
307///
308/// assert_eq!(parser("aB1c"), Ok(("1c", "aB")));
309/// assert_eq!(parser("1c"), Err(Err::Error(Error::new("1c", ErrorKind::Alpha))));
310/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Alpha))));
311/// ```
312///
313/// ```
314/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
315/// # use nom8::input::Streaming;
316/// # use nom8::character::alpha1;
317/// assert_eq!(alpha1::<_, (_, ErrorKind), true>(Streaming("aB1c")), Ok((Streaming("1c"), "aB")));
318/// assert_eq!(alpha1::<_, (_, ErrorKind), true>(Streaming("1c")), Err(Err::Error((Streaming("1c"), ErrorKind::Alpha))));
319/// assert_eq!(alpha1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
320/// ```
321#[inline(always)]
322pub fn alpha1<T, E: ParseError<T>, const STREAMING: bool>(
323 input: T,
324) -> IResult<T, <T as IntoOutput>::Output, E>
325where
326 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
327 T: IntoOutput,
328 <T as InputTakeAtPosition>::Item: AsChar,
329{
330 if STREAMING {
331 streaming::alpha1(input)
332 } else {
333 complete::alpha1(input)
334 }
335}
336
337/// Recognizes zero or more ASCII numerical characters: 0-9
338///
339/// *Complete version*: Will return an error if there's not enough input data,
340/// or the whole input if no terminating token is found (a non digit character).
341///
342/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
343/// or if no terminating token is found (a non digit character).
344///
345/// # Example
346///
347/// ```
348/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
349/// # use nom8::character::digit0;
350/// fn parser(input: &str) -> IResult<&str, &str> {
351/// digit0(input)
352/// }
353///
354/// assert_eq!(parser("21c"), Ok(("c", "21")));
355/// assert_eq!(parser("21"), Ok(("", "21")));
356/// assert_eq!(parser("a21c"), Ok(("a21c", "")));
357/// assert_eq!(parser(""), Ok(("", "")));
358/// ```
359///
360/// ```
361/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
362/// # use nom8::input::Streaming;
363/// # use nom8::character::digit0;
364/// assert_eq!(digit0::<_, (_, ErrorKind), true>(Streaming("21c")), Ok((Streaming("c"), "21")));
365/// assert_eq!(digit0::<_, (_, ErrorKind), true>(Streaming("a21c")), Ok((Streaming("a21c"), "")));
366/// assert_eq!(digit0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
367/// ```
368#[inline(always)]
369pub fn digit0<T, E: ParseError<T>, const STREAMING: bool>(
370 input: T,
371) -> IResult<T, <T as IntoOutput>::Output, E>
372where
373 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
374 T: IntoOutput,
375 <T as InputTakeAtPosition>::Item: AsChar,
376{
377 if STREAMING {
378 streaming::digit0(input)
379 } else {
380 complete::digit0(input)
381 }
382}
383
384/// Recognizes one or more ASCII numerical characters: 0-9
385///
386/// *Complete version*: Will return an error if there's not enough input data,
387/// or the whole input if no terminating token is found (a non digit character).
388///
389/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
390/// or if no terminating token is found (a non digit character).
391///
392/// # Example
393///
394/// ```
395/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
396/// # use nom8::character::digit1;
397/// fn parser(input: &str) -> IResult<&str, &str> {
398/// digit1(input)
399/// }
400///
401/// assert_eq!(parser("21c"), Ok(("c", "21")));
402/// assert_eq!(parser("c1"), Err(Err::Error(Error::new("c1", ErrorKind::Digit))));
403/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Digit))));
404/// ```
405///
406/// ```
407/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
408/// # use nom8::input::Streaming;
409/// # use nom8::character::digit1;
410/// assert_eq!(digit1::<_, (_, ErrorKind), true>(Streaming("21c")), Ok((Streaming("c"), "21")));
411/// assert_eq!(digit1::<_, (_, ErrorKind), true>(Streaming("c1")), Err(Err::Error((Streaming("c1"), ErrorKind::Digit))));
412/// assert_eq!(digit1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
413/// ```
414///
415/// ## Parsing an integer
416///
417/// You can use `digit1` in combination with [`Parser::map_res`][crate::Parser::map_res] to parse an integer:
418///
419/// ```
420/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed, Parser};
421/// # use nom8::character::digit1;
422/// fn parser(input: &str) -> IResult<&str, u32> {
423/// digit1.map_res(str::parse).parse(input)
424/// }
425///
426/// assert_eq!(parser("416"), Ok(("", 416)));
427/// assert_eq!(parser("12b"), Ok(("b", 12)));
428/// assert!(parser("b").is_err());
429/// ```
430#[inline(always)]
431pub fn digit1<T, E: ParseError<T>, const STREAMING: bool>(
432 input: T,
433) -> IResult<T, <T as IntoOutput>::Output, E>
434where
435 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
436 T: IntoOutput,
437 <T as InputTakeAtPosition>::Item: AsChar,
438{
439 if STREAMING {
440 streaming::digit1(input)
441 } else {
442 complete::digit1(input)
443 }
444}
445
446/// Recognizes zero or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
447///
448/// *Complete version*: Will return the whole input if no terminating token is found (a non hexadecimal digit character).
449///
450/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
451/// or if no terminating token is found (a non hexadecimal digit character).
452///
453/// # Example
454///
455/// ```
456/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
457/// # use nom8::character::hex_digit0;
458/// fn parser(input: &str) -> IResult<&str, &str> {
459/// hex_digit0(input)
460/// }
461///
462/// assert_eq!(parser("21cZ"), Ok(("Z", "21c")));
463/// assert_eq!(parser("Z21c"), Ok(("Z21c", "")));
464/// assert_eq!(parser(""), Ok(("", "")));
465/// ```
466///
467/// ```
468/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
469/// # use nom8::input::Streaming;
470/// # use nom8::character::hex_digit0;
471/// assert_eq!(hex_digit0::<_, (_, ErrorKind), true>(Streaming("21cZ")), Ok((Streaming("Z"), "21c")));
472/// assert_eq!(hex_digit0::<_, (_, ErrorKind), true>(Streaming("Z21c")), Ok((Streaming("Z21c"), "")));
473/// assert_eq!(hex_digit0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
474/// ```
475#[inline(always)]
476pub fn hex_digit0<T, E: ParseError<T>, const STREAMING: bool>(
477 input: T,
478) -> IResult<T, <T as IntoOutput>::Output, E>
479where
480 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
481 T: IntoOutput,
482 <T as InputTakeAtPosition>::Item: AsChar,
483{
484 if STREAMING {
485 streaming::hex_digit0(input)
486 } else {
487 complete::hex_digit0(input)
488 }
489}
490
491/// Recognizes one or more ASCII hexadecimal numerical characters: 0-9, A-F, a-f
492///
493/// *Complete version*: Will return an error if there's not enough input data,
494/// or the whole input if no terminating token is found (a non hexadecimal digit character).
495///
496/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
497/// or if no terminating token is found (a non hexadecimal digit character).
498///
499/// # Example
500///
501/// ```
502/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
503/// # use nom8::character::hex_digit1;
504/// fn parser(input: &str) -> IResult<&str, &str> {
505/// hex_digit1(input)
506/// }
507///
508/// assert_eq!(parser("21cZ"), Ok(("Z", "21c")));
509/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::HexDigit))));
510/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::HexDigit))));
511/// ```
512///
513/// ```
514/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
515/// # use nom8::input::Streaming;
516/// # use nom8::character::hex_digit1;
517/// assert_eq!(hex_digit1::<_, (_, ErrorKind), true>(Streaming("21cZ")), Ok((Streaming("Z"), "21c")));
518/// assert_eq!(hex_digit1::<_, (_, ErrorKind), true>(Streaming("H2")), Err(Err::Error((Streaming("H2"), ErrorKind::HexDigit))));
519/// assert_eq!(hex_digit1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
520/// ```
521#[inline(always)]
522pub fn hex_digit1<T, E: ParseError<T>, const STREAMING: bool>(
523 input: T,
524) -> IResult<T, <T as IntoOutput>::Output, E>
525where
526 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
527 T: IntoOutput,
528 <T as InputTakeAtPosition>::Item: AsChar,
529{
530 if STREAMING {
531 streaming::hex_digit1(input)
532 } else {
533 complete::hex_digit1(input)
534 }
535}
536
537/// Recognizes zero or more octal characters: 0-7
538///
539/// *Complete version*: Will return the whole input if no terminating token is found (a non octal
540/// digit character).
541///
542/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
543/// or if no terminating token is found (a non octal digit character).
544///
545/// # Example
546///
547/// ```
548/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
549/// # use nom8::character::oct_digit0;
550/// fn parser(input: &str) -> IResult<&str, &str> {
551/// oct_digit0(input)
552/// }
553///
554/// assert_eq!(parser("21cZ"), Ok(("cZ", "21")));
555/// assert_eq!(parser("Z21c"), Ok(("Z21c", "")));
556/// assert_eq!(parser(""), Ok(("", "")));
557/// ```
558///
559/// ```
560/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
561/// # use nom8::input::Streaming;
562/// # use nom8::character::oct_digit0;
563/// assert_eq!(oct_digit0::<_, (_, ErrorKind), true>(Streaming("21cZ")), Ok((Streaming("cZ"), "21")));
564/// assert_eq!(oct_digit0::<_, (_, ErrorKind), true>(Streaming("Z21c")), Ok((Streaming("Z21c"), "")));
565/// assert_eq!(oct_digit0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
566/// ```
567#[inline(always)]
568pub fn oct_digit0<T, E: ParseError<T>, const STREAMING: bool>(
569 input: T,
570) -> IResult<T, <T as IntoOutput>::Output, E>
571where
572 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
573 T: IntoOutput,
574 <T as InputTakeAtPosition>::Item: AsChar,
575{
576 if STREAMING {
577 streaming::oct_digit0(input)
578 } else {
579 complete::oct_digit0(input)
580 }
581}
582
583/// Recognizes one or more octal characters: 0-7
584///
585/// *Complete version*: Will return an error if there's not enough input data,
586/// or the whole input if no terminating token is found (a non octal digit character).
587///
588/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
589/// or if no terminating token is found (a non octal digit character).
590///
591/// # Example
592///
593/// ```
594/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
595/// # use nom8::character::oct_digit1;
596/// fn parser(input: &str) -> IResult<&str, &str> {
597/// oct_digit1(input)
598/// }
599///
600/// assert_eq!(parser("21cZ"), Ok(("cZ", "21")));
601/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::OctDigit))));
602/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::OctDigit))));
603/// ```
604///
605/// ```
606/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
607/// # use nom8::input::Streaming;
608/// # use nom8::character::oct_digit1;
609/// assert_eq!(oct_digit1::<_, (_, ErrorKind), true>(Streaming("21cZ")), Ok((Streaming("cZ"), "21")));
610/// assert_eq!(oct_digit1::<_, (_, ErrorKind), true>(Streaming("H2")), Err(Err::Error((Streaming("H2"), ErrorKind::OctDigit))));
611/// assert_eq!(oct_digit1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
612/// ```
613#[inline(always)]
614pub fn oct_digit1<T, E: ParseError<T>, const STREAMING: bool>(
615 input: T,
616) -> IResult<T, <T as IntoOutput>::Output, E>
617where
618 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
619 T: IntoOutput,
620 <T as InputTakeAtPosition>::Item: AsChar,
621{
622 if STREAMING {
623 streaming::oct_digit1(input)
624 } else {
625 complete::oct_digit1(input)
626 }
627}
628
629/// Recognizes zero or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
630///
631/// *Complete version*: Will return the whole input if no terminating token is found (a non
632/// alphanumerical character).
633///
634/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
635/// or if no terminating token is found (a non alphanumerical character).
636///
637/// # Example
638///
639/// ```
640/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
641/// # use nom8::character::alphanumeric0;
642/// fn parser(input: &str) -> IResult<&str, &str> {
643/// alphanumeric0(input)
644/// }
645///
646/// assert_eq!(parser("21cZ%1"), Ok(("%1", "21cZ")));
647/// assert_eq!(parser("&Z21c"), Ok(("&Z21c", "")));
648/// assert_eq!(parser(""), Ok(("", "")));
649/// ```
650///
651/// ```
652/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
653/// # use nom8::input::Streaming;
654/// # use nom8::character::alphanumeric0;
655/// assert_eq!(alphanumeric0::<_, (_, ErrorKind), true>(Streaming("21cZ%1")), Ok((Streaming("%1"), "21cZ")));
656/// assert_eq!(alphanumeric0::<_, (_, ErrorKind), true>(Streaming("&Z21c")), Ok((Streaming("&Z21c"), "")));
657/// assert_eq!(alphanumeric0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
658/// ```
659#[inline(always)]
660pub fn alphanumeric0<T, E: ParseError<T>, const STREAMING: bool>(
661 input: T,
662) -> IResult<T, <T as IntoOutput>::Output, E>
663where
664 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
665 T: IntoOutput,
666 <T as InputTakeAtPosition>::Item: AsChar,
667{
668 if STREAMING {
669 streaming::alphanumeric0(input)
670 } else {
671 complete::alphanumeric0(input)
672 }
673}
674
675/// Recognizes one or more ASCII numerical and alphabetic characters: 0-9, a-z, A-Z
676///
677/// *Complete version*: Will return an error if there's not enough input data,
678/// or the whole input if no terminating token is found (a non alphanumerical character).
679///
680/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
681/// or if no terminating token is found (a non alphanumerical character).
682///
683/// # Example
684///
685/// ```
686/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
687/// # use nom8::character::alphanumeric1;
688/// fn parser(input: &str) -> IResult<&str, &str> {
689/// alphanumeric1(input)
690/// }
691///
692/// assert_eq!(parser("21cZ%1"), Ok(("%1", "21cZ")));
693/// assert_eq!(parser("&H2"), Err(Err::Error(Error::new("&H2", ErrorKind::AlphaNumeric))));
694/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::AlphaNumeric))));
695/// ```
696///
697/// ```
698/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
699/// # use nom8::input::Streaming;
700/// # use nom8::character::alphanumeric1;
701/// assert_eq!(alphanumeric1::<_, (_, ErrorKind), true>(Streaming("21cZ%1")), Ok((Streaming("%1"), "21cZ")));
702/// assert_eq!(alphanumeric1::<_, (_, ErrorKind), true>(Streaming("&H2")), Err(Err::Error((Streaming("&H2"), ErrorKind::AlphaNumeric))));
703/// assert_eq!(alphanumeric1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
704/// ```
705#[inline(always)]
706pub fn alphanumeric1<T, E: ParseError<T>, const STREAMING: bool>(
707 input: T,
708) -> IResult<T, <T as IntoOutput>::Output, E>
709where
710 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
711 T: IntoOutput,
712 <T as InputTakeAtPosition>::Item: AsChar,
713{
714 if STREAMING {
715 streaming::alphanumeric1(input)
716 } else {
717 complete::alphanumeric1(input)
718 }
719}
720
721/// Recognizes zero or more spaces and tabs.
722///
723/// *Complete version*: Will return the whole input if no terminating token is found (a non space
724/// character).
725///
726/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
727/// or if no terminating token is found (a non space character).
728///
729/// # Example
730///
731/// ```
732/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
733/// # use nom8::input::Streaming;
734/// # use nom8::character::space0;
735/// assert_eq!(space0::<_, (_, ErrorKind), true>(Streaming(" \t21c")), Ok((Streaming("21c"), " \t")));
736/// assert_eq!(space0::<_, (_, ErrorKind), true>(Streaming("Z21c")), Ok((Streaming("Z21c"), "")));
737/// assert_eq!(space0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
738/// ```
739#[inline(always)]
740pub fn space0<T, E: ParseError<T>, const STREAMING: bool>(
741 input: T,
742) -> IResult<T, <T as IntoOutput>::Output, E>
743where
744 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
745 T: IntoOutput,
746 <T as InputTakeAtPosition>::Item: AsChar + Clone,
747{
748 if STREAMING {
749 streaming::space0(input)
750 } else {
751 complete::space0(input)
752 }
753}
754
755/// Recognizes one or more spaces and tabs.
756///
757/// *Complete version*: Will return an error if there's not enough input data,
758/// or the whole input if no terminating token is found (a non space character).
759///
760/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
761/// or if no terminating token is found (a non space character).
762///
763/// # Example
764///
765/// ```
766/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
767/// # use nom8::character::space1;
768/// fn parser(input: &str) -> IResult<&str, &str> {
769/// space1(input)
770/// }
771///
772/// assert_eq!(parser(" \t21c"), Ok(("21c", " \t")));
773/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::Space))));
774/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::Space))));
775/// ```
776///
777/// ```
778/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
779/// # use nom8::input::Streaming;
780/// # use nom8::character::space1;
781/// assert_eq!(space1::<_, (_, ErrorKind), true>(Streaming(" \t21c")), Ok((Streaming("21c"), " \t")));
782/// assert_eq!(space1::<_, (_, ErrorKind), true>(Streaming("H2")), Err(Err::Error((Streaming("H2"), ErrorKind::Space))));
783/// assert_eq!(space1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
784/// ```
785#[inline(always)]
786pub fn space1<T, E: ParseError<T>, const STREAMING: bool>(
787 input: T,
788) -> IResult<T, <T as IntoOutput>::Output, E>
789where
790 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
791 T: IntoOutput,
792 <T as InputTakeAtPosition>::Item: AsChar + Clone,
793{
794 if STREAMING {
795 streaming::space1(input)
796 } else {
797 complete::space1(input)
798 }
799}
800
801/// Recognizes zero or more spaces, tabs, carriage returns and line feeds.
802///
803/// *Complete version*: will return the whole input if no terminating token is found (a non space
804/// character).
805///
806/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
807/// or if no terminating token is found (a non space character).
808///
809/// # Example
810///
811/// ```
812/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
813/// # use nom8::character::multispace0;
814/// fn parser(input: &str) -> IResult<&str, &str> {
815/// multispace0(input)
816/// }
817///
818/// assert_eq!(parser(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
819/// assert_eq!(parser("Z21c"), Ok(("Z21c", "")));
820/// assert_eq!(parser(""), Ok(("", "")));
821/// ```
822///
823/// ```
824/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
825/// # use nom8::input::Streaming;
826/// # use nom8::character::multispace0;
827/// assert_eq!(multispace0::<_, (_, ErrorKind), true>(Streaming(" \t\n\r21c")), Ok((Streaming("21c"), " \t\n\r")));
828/// assert_eq!(multispace0::<_, (_, ErrorKind), true>(Streaming("Z21c")), Ok((Streaming("Z21c"), "")));
829/// assert_eq!(multispace0::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
830/// ```
831#[inline(always)]
832pub fn multispace0<T, E: ParseError<T>, const STREAMING: bool>(
833 input: T,
834) -> IResult<T, <T as IntoOutput>::Output, E>
835where
836 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
837 T: IntoOutput,
838 <T as InputTakeAtPosition>::Item: AsChar + Clone,
839{
840 if STREAMING {
841 streaming::multispace0(input)
842 } else {
843 complete::multispace0(input)
844 }
845}
846
847/// Recognizes one or more spaces, tabs, carriage returns and line feeds.
848///
849/// *Complete version*: will return an error if there's not enough input data,
850/// or the whole input if no terminating token is found (a non space character).
851///
852/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data,
853/// or if no terminating token is found (a non space character).
854///
855/// # Example
856///
857/// ```
858/// # use nom8::{Err, error::{Error, ErrorKind}, IResult, Needed};
859/// # use nom8::character::multispace1;
860/// fn parser(input: &str) -> IResult<&str, &str> {
861/// multispace1(input)
862/// }
863///
864/// assert_eq!(parser(" \t\n\r21c"), Ok(("21c", " \t\n\r")));
865/// assert_eq!(parser("H2"), Err(Err::Error(Error::new("H2", ErrorKind::MultiSpace))));
866/// assert_eq!(parser(""), Err(Err::Error(Error::new("", ErrorKind::MultiSpace))));
867/// ```
868///
869/// ```
870/// # use nom8::{Err, error::ErrorKind, IResult, Needed};
871/// # use nom8::input::Streaming;
872/// # use nom8::character::multispace1;
873/// assert_eq!(multispace1::<_, (_, ErrorKind), true>(Streaming(" \t\n\r21c")), Ok((Streaming("21c"), " \t\n\r")));
874/// assert_eq!(multispace1::<_, (_, ErrorKind), true>(Streaming("H2")), Err(Err::Error((Streaming("H2"), ErrorKind::MultiSpace))));
875/// assert_eq!(multispace1::<_, (_, ErrorKind), true>(Streaming("")), Err(Err::Incomplete(Needed::new(1))));
876/// ```
877#[inline(always)]
878pub fn multispace1<T, E: ParseError<T>, const STREAMING: bool>(
879 input: T,
880) -> IResult<T, <T as IntoOutput>::Output, E>
881where
882 T: InputTakeAtPosition + InputIsStreaming<STREAMING>,
883 T: IntoOutput,
884 <T as InputTakeAtPosition>::Item: AsChar + Clone,
885{
886 if STREAMING {
887 streaming::multispace1(input)
888 } else {
889 complete::multispace1(input)
890 }
891}
892
893#[doc(hidden)]
894macro_rules! ints {
895 ($($t:tt)+) => {
896 $(
897 /// will parse a number in text form to a number
898 ///
899 /// *Complete version*: can parse until the end of input.
900 ///
901 /// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
902 #[inline(always)]
903 pub fn $t<T, E: ParseError<T>, const STREAMING: bool>(input: T) -> IResult<T, $t, E>
904 where
905 T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputTake + Clone + InputIsStreaming<STREAMING>,
906 T: IntoOutput,
907 <T as InputIter>::Item: AsChar,
908 T: for <'a> Compare<&'a[u8]>,
909 {
910 if STREAMING {
911 streaming::$t(input)
912 } else {
913 complete::$t(input)
914 }
915 }
916 )+
917 }
918}
919
920ints! { i8 i16 i32 i64 i128 }
921
922#[doc(hidden)]
923macro_rules! uints {
924 ($($t:tt)+) => {
925 $(
926 /// will parse a number in text form to a number
927 ///
928 /// *Complete version*: can parse until the end of input.
929 ///
930 /// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there's not enough input data.
931 #[inline(always)]
932 pub fn $t<T, E: ParseError<T>, const STREAMING: bool>(input: T) -> IResult<T, $t, E>
933 where
934 T: InputIter + Slice<RangeFrom<usize>> + InputLength + InputIsStreaming<STREAMING>,
935 T: IntoOutput,
936 <T as InputIter>::Item: AsChar,
937 {
938 if STREAMING {
939 streaming::$t(input)
940 } else {
941 complete::$t(input)
942 }
943 }
944 )+
945 }
946}
947
948uints! { u8 u16 u32 u64 u128 }
949
950/// Recognizes floating point number in text format and returns a f32.
951///
952/// *Complete version*: Can parse until the end of input.
953///
954/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there is not enough data.
955///
956/// # Example
957///
958/// ```rust
959/// # use nom8::{Err, error::ErrorKind, Needed};
960/// # use nom8::Needed::Size;
961/// use nom8::character::f32;
962///
963/// let parser = |s| {
964/// f32(s)
965/// };
966///
967/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
968/// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
969/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
970/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
971/// ```
972///
973/// ```rust
974/// # use nom8::{Err, error::ErrorKind, Needed};
975/// # use nom8::Needed::Size;
976/// # use nom8::input::Streaming;
977/// use nom8::character::f32;
978///
979/// let parser = |s| {
980/// f32(s)
981/// };
982///
983/// assert_eq!(parser(Streaming("11e-1 ")), Ok((Streaming(" "), 1.1)));
984/// assert_eq!(parser(Streaming("11e-1")), Err(Err::Incomplete(Needed::new(1))));
985/// assert_eq!(parser(Streaming("123E-02")), Err(Err::Incomplete(Needed::new(1))));
986/// assert_eq!(parser(Streaming("123K-01")), Ok((Streaming("K-01"), 123.0)));
987/// assert_eq!(parser(Streaming("abc")), Err(Err::Error((Streaming("abc"), ErrorKind::Float))));
988/// ```
989#[inline(always)]
990pub fn f32<T, E: ParseError<T>, const STREAMING: bool>(input: T) -> IResult<T, f32, E>
991where
992 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
993 T: Clone + Offset + Compare<&'static str>,
994 T: InputIter + InputLength + InputTake + InputIsStreaming<STREAMING>,
995 T: IntoOutput,
996 <T as IntoOutput>::Output: ParseTo<f32>,
997 <T as InputIter>::Item: AsChar + Copy,
998 <T as InputIter>::IterElem: Clone,
999 T: InputTakeAtPosition,
1000 <T as InputTakeAtPosition>::Item: AsChar,
1001 T: AsBytes,
1002 T: for<'a> Compare<&'a [u8]>,
1003{
1004 if STREAMING {
1005 crate::number::streaming::float(input)
1006 } else {
1007 crate::number::complete::float(input)
1008 }
1009}
1010
1011/// Recognizes floating point number in text format and returns a f64.
1012///
1013/// *Complete version*: Can parse until the end of input.
1014///
1015/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there is not enough data.
1016///
1017/// # Example
1018///
1019/// ```rust
1020/// # use nom8::{Err, error::ErrorKind, Needed};
1021/// # use nom8::Needed::Size;
1022/// use nom8::character::f64;
1023///
1024/// let parser = |s| {
1025/// f64(s)
1026/// };
1027///
1028/// assert_eq!(parser("11e-1"), Ok(("", 1.1)));
1029/// assert_eq!(parser("123E-02"), Ok(("", 1.23)));
1030/// assert_eq!(parser("123K-01"), Ok(("K-01", 123.0)));
1031/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Float))));
1032/// ```
1033///
1034/// ```rust
1035/// # use nom8::{Err, error::ErrorKind, Needed};
1036/// # use nom8::Needed::Size;
1037/// # use nom8::input::Streaming;
1038/// use nom8::character::f64;
1039///
1040/// let parser = |s| {
1041/// f64(s)
1042/// };
1043///
1044/// assert_eq!(parser(Streaming("11e-1 ")), Ok((Streaming(" "), 1.1)));
1045/// assert_eq!(parser(Streaming("11e-1")), Err(Err::Incomplete(Needed::new(1))));
1046/// assert_eq!(parser(Streaming("123E-02")), Err(Err::Incomplete(Needed::new(1))));
1047/// assert_eq!(parser(Streaming("123K-01")), Ok((Streaming("K-01"), 123.0)));
1048/// assert_eq!(parser(Streaming("abc")), Err(Err::Error((Streaming("abc"), ErrorKind::Float))));
1049/// ```
1050#[inline(always)]
1051pub fn f64<T, E: ParseError<T>, const STREAMING: bool>(input: T) -> IResult<T, f64, E>
1052where
1053 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
1054 T: Clone + Offset + Compare<&'static str>,
1055 T: InputIter + InputLength + InputTake + InputIsStreaming<STREAMING>,
1056 T: IntoOutput,
1057 <T as IntoOutput>::Output: ParseTo<f64>,
1058 <T as InputIter>::Item: AsChar + Copy,
1059 <T as InputIter>::IterElem: Clone,
1060 T: InputTakeAtPosition,
1061 <T as InputTakeAtPosition>::Item: AsChar,
1062 T: AsBytes,
1063 T: for<'a> Compare<&'a [u8]>,
1064{
1065 if STREAMING {
1066 crate::number::streaming::double(input)
1067 } else {
1068 crate::number::complete::double(input)
1069 }
1070}
1071
1072/// Recognizes floating point number in a byte string and returns the corresponding slice.
1073///
1074/// *Complete version*: Can parse until the end of input.
1075///
1076/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there is not enough data.
1077///
1078/// # Example
1079///
1080/// ```rust
1081/// # use nom8::{Err, error::ErrorKind, Needed};
1082/// # use nom8::Needed::Size;
1083/// use nom8::character::recognize_float;
1084///
1085/// let parser = |s| {
1086/// recognize_float(s)
1087/// };
1088///
1089/// assert_eq!(parser("11e-1"), Ok(("", "11e-1")));
1090/// assert_eq!(parser("123E-02"), Ok(("", "123E-02")));
1091/// assert_eq!(parser("123K-01"), Ok(("K-01", "123")));
1092/// assert_eq!(parser("abc"), Err(Err::Error(("abc", ErrorKind::Char))));
1093/// ```
1094///
1095/// ```rust
1096/// # use nom8::{Err, error::ErrorKind, Needed};
1097/// # use nom8::input::Streaming;
1098/// use nom8::character::recognize_float;
1099///
1100/// let parser = |s| {
1101/// recognize_float(s)
1102/// };
1103///
1104/// assert_eq!(parser(Streaming("11e-1;")), Ok((Streaming(";"), "11e-1")));
1105/// assert_eq!(parser(Streaming("123E-02;")), Ok((Streaming(";"), "123E-02")));
1106/// assert_eq!(parser(Streaming("123K-01")), Ok((Streaming("K-01"), "123")));
1107/// assert_eq!(parser(Streaming("abc")), Err(Err::Error((Streaming("abc"), ErrorKind::Char))));
1108/// ```
1109#[inline(always)]
1110pub fn recognize_float<T, E: ParseError<T>, const STREAMING: bool>(
1111 input: T,
1112) -> IResult<T, <T as IntoOutput>::Output, E>
1113where
1114 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>>,
1115 T: Clone + Offset,
1116 T: InputIter + InputLength + InputIsStreaming<STREAMING>,
1117 T: IntoOutput,
1118 <T as InputIter>::Item: AsChar,
1119 T: InputTakeAtPosition,
1120 <T as InputTakeAtPosition>::Item: AsChar,
1121{
1122 if STREAMING {
1123 crate::number::streaming::recognize_float(input)
1124 } else {
1125 crate::number::complete::recognize_float(input)
1126 }
1127}
1128
1129/// Recognizes a floating point number in text format
1130///
1131/// It returns a tuple of (`sign`, `integer part`, `fraction part` and `exponent`) of the input
1132/// data.
1133///
1134/// *Complete version*: Can parse until the end of input.
1135///
1136/// *Streaming version*: Will return `Err(nom8::Err::Incomplete(_))` if there is not enough data.
1137///
1138#[inline(always)]
1139pub fn recognize_float_parts<T, E: ParseError<T>, const STREAMING: bool>(
1140 input: T,
1141) -> IResult<
1142 T,
1143 (
1144 bool,
1145 <T as IntoOutput>::Output,
1146 <T as IntoOutput>::Output,
1147 i32,
1148 ),
1149 E,
1150>
1151where
1152 T: Slice<RangeFrom<usize>> + Slice<RangeTo<usize>> + Slice<Range<usize>>,
1153 T: Clone + Offset,
1154 T: InputIter + InputTake + InputIsStreaming<STREAMING>,
1155 T: IntoOutput,
1156 <T as InputIter>::Item: AsChar + Copy,
1157 T: InputTakeAtPosition + InputLength,
1158 <T as InputTakeAtPosition>::Item: AsChar,
1159 T: for<'a> Compare<&'a [u8]>,
1160 T: AsBytes,
1161{
1162 if STREAMING {
1163 crate::number::streaming::recognize_float_parts(input)
1164 } else {
1165 crate::number::complete::recognize_float_parts(input)
1166 }
1167}
1168
1169#[inline]
1170#[doc(hidden)]
1171#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_alpha`")]
1172pub fn is_alphabetic(chr: u8) -> bool {
1173 (chr >= 0x41 && chr <= 0x5A) || (chr >= 0x61 && chr <= 0x7A)
1174}
1175
1176#[inline]
1177#[doc(hidden)]
1178#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_dec_digit`")]
1179pub fn is_digit(chr: u8) -> bool {
1180 chr >= 0x30 && chr <= 0x39
1181}
1182
1183#[inline]
1184#[doc(hidden)]
1185#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_hex_digit`")]
1186pub fn is_hex_digit(chr: u8) -> bool {
1187 (chr >= 0x30 && chr <= 0x39) || (chr >= 0x41 && chr <= 0x46) || (chr >= 0x61 && chr <= 0x66)
1188}
1189
1190#[inline]
1191#[doc(hidden)]
1192#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_oct_digit`")]
1193pub fn is_oct_digit(chr: u8) -> bool {
1194 chr >= 0x30 && chr <= 0x37
1195}
1196
1197#[inline]
1198#[doc(hidden)]
1199#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_alphanum`")]
1200pub fn is_alphanumeric(chr: u8) -> bool {
1201 #![allow(deprecated)]
1202 is_alphabetic(chr) || is_digit(chr)
1203}
1204
1205#[inline]
1206#[doc(hidden)]
1207#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_space`")]
1208pub fn is_space(chr: u8) -> bool {
1209 chr == b' ' || chr == b'\t'
1210}
1211
1212#[inline]
1213#[doc(hidden)]
1214#[deprecated(since = "8.0.0", note = "Replaced with `AsChar::is_newline`")]
1215pub fn is_newline(chr: u8) -> bool {
1216 chr == b'\n'
1217}