///|
/// The kind of rule selected by the Public Suffix List algorithm.
pub(all) enum RuleKind {
DefaultRule
ExactRule
WildcardRule
ExceptionRule
} derive(Eq, Debug)
///|
/// The PSL source section that supplied a prevailing rule.
pub(all) enum RuleSection {
UnsectionedRule
IcannSection
PrivateSection
} derive(Eq, Debug)
///|
/// The PSL sections eligible for a lookup.
pub(all) enum SectionScope {
IcannAndPrivate
IcannOnly
} derive(Eq, Debug)
///|
/// The behavior used when no eligible explicit rule matches a hostname.
pub(all) enum UnknownSuffixPolicy {
UseDefaultWildcard
RequireListedSuffix
} derive(Eq, Debug)
///|
/// Explicit policy controls for a public-suffix lookup.
pub struct LookupOptions {
scope : SectionScope
unknown_suffix : UnknownSuffixPolicy
}
///|
/// Construct lookup options from an eligible-section scope and unknown-suffix
/// policy.
pub fn LookupOptions::new(
scope : SectionScope,
unknown_suffix : UnknownSuffixPolicy,
) -> LookupOptions {
{ scope, unknown_suffix, }
}
///|
/// Return browser-style defaults: ICANN and PRIVATE rules plus implicit `*`.
pub fn LookupOptions::browser_default() -> LookupOptions {
{ scope: IcannAndPrivate, unknown_suffix: UseDefaultWildcard, }
}
///|
/// Return a conservative policy that accepts only listed ICANN suffixes.
pub fn LookupOptions::strict_icann() -> LookupOptions {
{ scope: IcannOnly, unknown_suffix: RequireListedSuffix, }
}
///|
pub fn LookupOptions::section_scope(self : LookupOptions) -> SectionScope {
self.scope
}
///|
pub fn LookupOptions::unknown_suffix_policy(
self : LookupOptions,
) -> UnknownSuffixPolicy {
self.unknown_suffix
}
///|
/// An explainable public-suffix lookup result.
///
/// `normalized_domain` is case-normalized only. Callers are responsible for
/// applying the same IDNA profile to the list and hostname before lookup.
pub struct Lookup {
normalized_domain : String
public_suffix : String
registrable_domain : String?
matched_rule : String
rule_kind : RuleKind
rule_section : RuleSection?
}
///|
/// Return the case-normalized input domain, preserving one trailing root dot.
pub fn Lookup::normalized_domain(self : Lookup) -> String {
self.normalized_domain
}
///|
/// Return the public suffix selected by the prevailing rule.
pub fn Lookup::public_suffix(self : Lookup) -> String {
self.public_suffix
}
///|
/// Return the public suffix plus one label, if that label exists.
pub fn Lookup::registrable_domain(self : Lookup) -> String? {
self.registrable_domain
}
///|
/// Return the prevailing PSL rule, including `*.` or `!` when applicable.
pub fn Lookup::matched_rule(self : Lookup) -> String {
self.matched_rule
}
///|
/// Return the kind of the prevailing rule.
pub fn Lookup::rule_kind(self : Lookup) -> RuleKind {
self.rule_kind
}
///|
/// Return the source section of the prevailing explicit rule. The implicit
/// default wildcard has no source section.
pub fn Lookup::rule_section(self : Lookup) -> RuleSection? {
self.rule_section
}
///|
/// A malformed rule in caller-supplied PSL text.
pub(all) enum ListParseError {
InvalidRule(Int, String, String)
} derive(Eq, Debug)
///|
pub fn ListParseError::message(self : ListParseError) -> String {
match self {
InvalidRule(line, rule, reason) =>
"invalid PSL rule on line \{line} ('\{rule}'): \{reason}"
}
}
///|
/// A hostname that cannot be split into valid lookup labels.
pub(all) enum DomainError {
EmptyDomain
EmptyLabel(Int)
InvalidDomainCharacter(Int, Char)
UnlistedSuffix(String)
} derive(Eq, Debug)
///|
pub fn DomainError::message(self : DomainError) -> String {
match self {
EmptyDomain => "domain is empty"
EmptyLabel(index) => "domain contains an empty label at index \{index}"
InvalidDomainCharacter(index, character) =>
"domain label \{index} contains invalid character '\{character}'"
UnlistedSuffix(domain) =>
"domain '\{domain}' has no suffix listed by the selected policy"
}
}
///|
/// A compiled, immutable-by-API Public Suffix List rule set.
pub struct SuffixList {
children : Array[Map[String, Int]]
exact_sections : Array[Array[RuleSection]]
wildcard_sections : Array[Array[RuleSection]]
exception_sections : Array[Array[RuleSection]]
rule_count_ : Int
}
///|
/// Return the number of distinct rules compiled into this list.
pub fn SuffixList::rule_count(self : SuffixList) -> Int {
self.rule_count_
}
///|
/// Return the number of trie nodes used by this compiled list.
pub fn SuffixList::node_count(self : SuffixList) -> Int {
self.children.length()
}