1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! IRI validator.
//!
//! About IRI, see [RFC 3987 Internationalized Resource Identifiers (IRIs)][RFC 3987].
//!
//! [RFC 3987]: https://tools.ietf.org/html/rfc3987

use std::{error, fmt};

use nom::combinator::all_consuming;

use crate::parser::{self, IriRule};

/// [RFC 3987] IRI validation error.
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Error(());

impl Error {
    /// Creates a new `Error`.
    ///
    /// For internal use.
    pub(crate) fn new() -> Self {
        Error(())
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Invalid IRI")
    }
}

impl error::Error for Error {}

/// Converts the given result into a validation result.
fn conv_err<T, E>(res: Result<T, E>) -> Result<(), Error> {
    match res {
        Ok(_) => Ok(()),
        Err(_) => Err(Error(())),
    }
}

/// Validates [RFC 3987] [IRI][uri].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [uri]: https://tools.ietf.org/html/rfc3986#section-3
pub fn iri(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::uri::<(), IriRule>)(s))
}

/// Validates [RFC 3987] [IRI reference][uri-reference].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [uri-reference]: https://tools.ietf.org/html/rfc3986#section-4.1
pub fn iri_reference(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::uri_reference::<(), IriRule>)(s))
}

/// Validates [RFC 3987] [absolute IRI][absolute-uri].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [absolute-uri]: https://tools.ietf.org/html/rfc3986#section-4.3
pub fn absolute_iri(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::absolute_uri::<(), IriRule>)(s))
}

/// Validates [RFC 3987] [relative reference][relative-ref].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [relative-ref]: https://tools.ietf.org/html/rfc3986#section-4.2
pub fn relative_ref(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::relative_ref::<(), IriRule>)(s))
}

/// Validates [RFC 3987] [IRI path][path].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [path]: https://tools.ietf.org/html/rfc3986#section-3.3
pub fn path(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::path::<(), IriRule>)(s))
}

/// Validates [RFC 3987] [IRI fragment][fragment].
///
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [fragment]: https://tools.ietf.org/html/rfc3986#section-3.5
pub fn fragment(s: &str) -> Result<(), Error> {
    conv_err(all_consuming(parser::fragment::<(), IriRule>)(s))
}