nom_rfc8288/
lib.rs

1//! This crate provides utilities for parsing `Link` headers. See the [complete::link] method
2//! for more info
3
4#![deny(rustdoc::broken_intra_doc_links)]
5
6use nom::{AsChar, IResult, Input, Parser, error::ParseError};
7
8pub mod complete;
9pub mod streaming;
10
11/// Token character
12///
13/// ```text
14/// TCHAR = "!" / "#" / "$" / "%" / "&" / "'" / "*"
15///       / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
16///       / DIGIT / ALPHA
17/// ```
18pub fn is_tchar(c: impl AsChar) -> bool {
19    // This is implemented as one match statement because to call
20    // is_alpha and is_digit would impose the Copy trait on this
21    // function call
22    matches!(c.as_char(),
23             '!' | '#' | '$' | '%' | '&' | '\'' | '*' |
24             '+' | '-' | '.' | '^' | '_' | '`' | '|' | '~' |
25             '\x41'..='\x5A' | '\x61'..='\x7A' | // A-Z, a-z
26             '\x30'..='\x39' // Digits
27    )
28}
29
30/// `QDTEXT = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text`
31pub fn is_qdtext(c: impl AsChar) -> bool {
32    matches!(c.as_char(), '\t' | ' ' | '\x21' | '\x23' ..= '\x5B' | '\x5D' ..= '\x7E' | '\u{80}' ..= '\u{FF}')
33}
34
35/// Only implements the `( HTAB / SP / VCHAR / obs-text )` component of QUOTED-PAIR
36fn is_quoted_pair(c: impl AsChar) -> bool {
37    // https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
38    matches!(c.as_char(), '\t' | ' ' | '\x21' ..= '\x7E' | '\u{80}' ..= '\u{FF}')
39}
40
41/// If the condition is true, this parser only returns `Some` or `None`
42fn optional_parser<I, O, E, L>(
43    condition: bool,
44    mut element: L,
45) -> impl FnMut(I) -> IResult<I, Option<O>, E>
46where
47    L: Parser<I, Error = E, Output = O>,
48    E: ParseError<I>,
49    I: Input + Copy + std::marker::Copy,
50{
51    move |input: I| {
52        let res = element.parse(input);
53
54        if condition {
55            return Ok(match res {
56                Ok((k, j)) => (k, Some(j)),
57                Err(_) => (input, None),
58            });
59        }
60
61        match res {
62            Ok((k, j)) => Ok((k, Some(j))),
63            Err(e) => Err(e),
64        }
65    }
66}
67
68#[doc = include_str!("../README.md")]
69#[cfg(doctest)]
70pub struct ReadmeDoctests;