iri_string/spec/
internal.rs

1//! A private module for sealed trait and internal implementations.
2//!
3//! Note that this MUST be a private module.
4//! See [Rust API Guidelines][sealed-trait] about the necessity of being private.
5//!
6//! [sealed-trait]:
7//! https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
8
9use crate::parser::char::is_ucschar;
10use crate::spec::{IriSpec, UriSpec};
11
12/// A trait to prohibit user-defined types from implementing `Spec`.
13///
14/// About sealed trait, see [Rust API Guidelines][future-proofing].
15///
16/// [future-proofing]: https://rust-lang.github.io/api-guidelines/future-proofing.html
17pub trait Sealed: SpecInternal {}
18
19impl Sealed for IriSpec {}
20impl Sealed for UriSpec {}
21
22/// Internal implementations for spec types.
23pub trait SpecInternal: Sized {
24    /// Checks if the given non-ASCII character matches `unreserved` or `iunreserved` rule.
25    #[must_use]
26    fn is_nonascii_char_unreserved(c: char) -> bool;
27    /// Checks if the given character matches `iprivate` rule.
28    #[must_use]
29    fn is_nonascii_char_private(c: char) -> bool;
30}
31
32impl SpecInternal for IriSpec {
33    #[inline]
34    fn is_nonascii_char_unreserved(c: char) -> bool {
35        is_ucschar(c)
36    }
37
38    fn is_nonascii_char_private(c: char) -> bool {
39        matches!(
40            u32::from(c),
41            0xE000..=0xF8FF |
42            0xF_0000..=0xF_FFFD |
43            0x10_0000..=0x10_FFFD
44        )
45    }
46}
47
48impl SpecInternal for UriSpec {
49    #[inline]
50    fn is_nonascii_char_unreserved(_: char) -> bool {
51        false
52    }
53
54    #[inline]
55    fn is_nonascii_char_private(_: char) -> bool {
56        false
57    }
58}