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}