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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Absolute IRI (without fragment part).
#[cfg(feature = "alloc")]
use crate::types::{RiReferenceString, RiString};
use crate::{
types::{RiReferenceStr, RiStr},
validate::absolute_iri,
};
define_custom_string_slice! {
/// A borrowed slice of an absolute IRI without fragment part.
///
/// This corresponds to [`absolute-IRI` rule] in [RFC 3987]
/// (and [`absolute-URI` rule] in [RFC 3986]).
/// In other words, this is [`RiStr`] without fragment part.
///
/// If you want to accept fragment part, use [`RiStr`].
///
/// # Valid values
///
/// This type can have an absolute IRI without fragment part.
///
/// ```
/// # use iri_string::types::IriAbsoluteStr;
/// assert!(IriAbsoluteStr::new("https://example.com/foo?bar=baz").is_ok());
/// assert!(IriAbsoluteStr::new("foo:bar").is_ok());
/// // Scheme `foo` and empty path.
/// assert!(IriAbsoluteStr::new("foo:").is_ok());
/// // `foo://.../` below are all allowed. See the crate documentation for detail.
/// assert!(IriAbsoluteStr::new("foo:/").is_ok());
/// assert!(IriAbsoluteStr::new("foo://").is_ok());
/// assert!(IriAbsoluteStr::new("foo:///").is_ok());
/// assert!(IriAbsoluteStr::new("foo:////").is_ok());
/// assert!(IriAbsoluteStr::new("foo://///").is_ok());
///
/// ```
///
/// Relative IRI is not allowed.
///
/// ```
/// # use iri_string::types::IriAbsoluteStr;
/// // This is relative path.
/// assert!(IriAbsoluteStr::new("foo/bar").is_err());
/// // `/foo/bar` is an absolute path, but it is authority-relative.
/// assert!(IriAbsoluteStr::new("/foo/bar").is_err());
/// // `//foo/bar` is termed "network-path reference",
/// // or usually called "protocol-relative reference".
/// assert!(IriAbsoluteStr::new("//foo/bar").is_err());
/// // Empty string is not a valid absolute IRI.
/// assert!(IriAbsoluteStr::new("").is_err());
/// ```
///
/// Fragment part (such as trailing `#foo`) is not allowed.
///
/// ```
/// # use iri_string::types::IriAbsoluteStr;
/// // Fragment part is not allowed.
/// assert!(IriAbsoluteStr::new("https://example.com/foo?bar=baz#qux").is_err());
/// ```
///
/// Some characters and sequences cannot used in an absolute IRI.
///
/// ```
/// # use iri_string::types::IriAbsoluteStr;
/// // `<` and `>` cannot directly appear in an absolute IRI.
/// assert!(IriAbsoluteStr::new("<not allowed>").is_err());
/// // Broken percent encoding cannot appear in an absolute IRI.
/// assert!(IriAbsoluteStr::new("%").is_err());
/// assert!(IriAbsoluteStr::new("%GG").is_err());
/// ```
///
/// [RFC 3986]: https://tools.ietf.org/html/rfc3986
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [`absolute-IRI` rule]: https://tools.ietf.org/html/rfc3987#section-2.2
/// [`absolute-URI` rule]: https://tools.ietf.org/html/rfc3986#section-4.3
/// [`RiStr`]: struct.RiStr.html
struct RiAbsoluteStr {
validator = absolute_iri,
expecting_msg = "Absolute IRI string",
}
}
#[cfg(feature = "alloc")]
define_custom_string_owned! {
/// An owned string of an absolute IRI without fragment part.
///
/// This corresponds to [`absolute-IRI` rule] in [RFC 3987]
/// (and [`absolute-URI` rule] in [RFC 3986]).
/// The rule for `absolute-IRI` is `scheme ":" ihier-part [ "?" iquery ]`.
/// In other words, this is [`RiString`] without fragment part.
///
/// If you want to accept fragment part, use [`RiString`].
///
/// For details, see the document for [`RiAbsoluteStr`].
///
/// Enabled by `alloc` or `std` feature.
///
/// [RFC 3986]: https://tools.ietf.org/html/rfc3986
/// [RFC 3987]: https://tools.ietf.org/html/rfc3987
/// [`absolute-IRI` rule]: https://tools.ietf.org/html/rfc3987#section-2.2
/// [`absolute-URI` rule]: https://tools.ietf.org/html/rfc3986#section-4.3
/// [`RiAbsoluteStr`]: struct.RiAbsoluteStr.html
/// [`RiString`]: struct.RiString.html
struct RiAbsoluteString {
validator = absolute_iri,
slice = RiAbsoluteStr,
expecting_msg = "Absolute IRI string",
}
}
impl_infallible_conv_between_iri! {
from_slice: RiAbsoluteStr,
from_owned: RiAbsoluteString,
to_slice: RiStr,
to_owned: RiString,
}
impl_infallible_conv_between_iri! {
from_slice: RiAbsoluteStr,
from_owned: RiAbsoluteString,
to_slice: RiReferenceStr,
to_owned: RiReferenceString,
}