···3535 | Domain_is_public_suffix
36363737let pp_error fmt = function
3838- | Empty_domain -> Format.fprintf fmt "Empty domain"
3939- | Invalid_domain s -> Format.fprintf fmt "Invalid domain: %s" s
4040- | Leading_dot -> Format.fprintf fmt "Domain has a leading dot"
4141- | Punycode_error s -> Format.fprintf fmt "Punycode conversion error: %s" s
4242- | No_public_suffix -> Format.fprintf fmt "No public suffix found"
4343- | Domain_is_public_suffix ->
4444- Format.fprintf fmt "Domain is itself a public suffix"
3838+ | Empty_domain -> Fmt.pf fmt "Empty domain"
3939+ | Invalid_domain s -> Fmt.pf fmt "Invalid domain: %s" s
4040+ | Leading_dot -> Fmt.pf fmt "Domain has a leading dot"
4141+ | Punycode_error s -> Fmt.pf fmt "Punycode conversion error: %s" s
4242+ | No_public_suffix -> Fmt.pf fmt "No public suffix found"
4343+ | Domain_is_public_suffix -> Fmt.pf fmt "Domain is itself a public suffix"
45444646-let error_to_string err = Format.asprintf "%a" pp_error err
4747-let create () = { root = Publicsuffix_data.get_root () }
4545+let error_to_string err = Fmt.str "%a" pp_error err
4646+let v () = { root = Publicsuffix_data.root () }
4747+let pp fmt _t = Fmt.pf fmt "<Publicsuffix>"
48484949(* Find a child node by label (case-insensitive) *)
5050-let find_child (node : trie_node) label =
5050+let child (node : trie_node) label =
5151 let label_lower = String.lowercase_ascii label in
5252 List.find_opt
5353 (fun (l, _) -> String.lowercase_ascii l = label_lower)
···63636464(** Find all matching rules for a domain. Labels should be in reverse order (TLD
6565 first). *)
6666-let find_matches (root : trie_node) labels =
6666+let matches (root : trie_node) labels =
6767 let matches = ref [] in
68686969 (* Track whether we matched the implicit * rule *)
···110110 wc.rule);
111111112112 (* Check for exact label match *)
113113- find_child node label
114114- |> Option.iter (fun child -> traverse child (depth + 1) rest)
113113+ child node label |> Option.iter (fun c -> traverse c (depth + 1) rest)
115114 in
116115117116 traverse root 0 labels;
···155154 match
156155 try Ok (Punycode_idna.to_ascii domain)
157156 with Punycode_idna.Error e ->
158158- let msg = Format.asprintf "%a" Punycode_idna.pp_error_reason e in
157157+ let msg = Fmt.str "%a" Punycode_idna.pp_error_reason e in
159158 Error (Punycode_error msg)
160159 with
161160 | Error e -> Error e
···187186 else prevailing.matched_labels
188187189188(** Find the prevailing rule for a domain *)
190190-let find_prevailing_rule t labels =
189189+let prevailing_rule t labels =
191190 let rev_labels = List.rev labels in
192192- let matches = find_matches t.root rev_labels in
193193- select_prevailing_rule matches
191191+ let ms = matches t.root rev_labels in
192192+ select_prevailing_rule ms
194193195194let public_suffix_with_section t domain =
196195 match normalize_domain domain with
197196 | Error e -> Error e
198197 | Ok (labels, has_trailing_dot) ->
199199- let prevailing = find_prevailing_rule t labels in
198198+ let prevailing = prevailing_rule t labels in
200199 let count = suffix_label_count prevailing in
201200 if count > List.length labels then Error No_public_suffix
202201 else
···211210 match normalize_domain domain with
212211 | Error e -> Error e
213212 | Ok (labels, has_trailing_dot) ->
214214- let prevailing = find_prevailing_rule t labels in
213213+ let prevailing = prevailing_rule t labels in
215214 let count = suffix_label_count prevailing in
216215 (* Registrable domain = suffix + 1 label *)
217216 let reg_label_count = count + 1 in
···228227 match normalize_domain domain with
229228 | Error e -> Error e
230229 | Ok (labels, _) ->
231231- let prevailing = find_prevailing_rule t labels in
230230+ let prevailing = prevailing_rule t labels in
232231 let count = suffix_label_count prevailing in
233232 (* Domain is a public suffix if it has exactly suffix_label_count labels *)
234233 Ok (List.length labels = count)
···237236 match normalize_domain domain with
238237 | Error e -> Error e
239238 | Ok (labels, _) ->
240240- let prevailing = find_prevailing_rule t labels in
239239+ let prevailing = prevailing_rule t labels in
241240 let count = suffix_label_count prevailing in
242241 let reg_label_count = count + 1 in
243242 (* Domain is registrable if it has exactly reg_label_count labels *)
+36-33
lib/publicsuffix.mli
···5050 {1 Example Usage}
51515252 {[
5353- let psl = Publicsuffix.create () in
5353+ let psl = Publicsuffix.v () in
54545555- (* Get the public suffix of a domain *)
5656- Publicsuffix.public_suffix psl "www.example.com" (* Returns: Ok "com" *)
5757- Publicsuffix.public_suffix psl
5858- "www.example.co.uk" (* Returns: Ok "co.uk" *)
5959- (* Get the registrable domain *)
6060- Publicsuffix.registrable_domain psl
6161- "www.example.com" (* Returns: Ok "example.com" *)
6262- (* Check if a domain is a public suffix *)
6363- Publicsuffix.is_public_suffix psl "com" (* Returns: Ok true *)
6464- Publicsuffix.is_public_suffix psl "example.com"
6565- (* Returns: Ok false *)
5555+ (* Get the public suffix of a domain *)
5656+ Publicsuffix.public_suffix psl "www.example.com" (* Returns: Ok "com" *)
5757+ Publicsuffix.public_suffix psl
5858+ "www.example.co.uk" (* Returns: Ok "co.uk" *)
5959+ (* Get the registrable domain *)
6060+ Publicsuffix.registrable_domain psl
6161+ "www.example.com" (* Returns: Ok "example.com" *)
6262+ (* Check if a domain is a public suffix *)
6363+ Publicsuffix.is_public_suffix psl "com" (* Returns: Ok true *)
6464+ Publicsuffix.is_public_suffix psl "example.com"
6565+ (* Returns: Ok false *)
6666 ]}
67676868 {1 Internationalized Domain Names}
···8181 encoding implementation. Both Unicode and Punycode input are accepted:
82828383 {[
8484- Publicsuffix.registrable_domain psl
8585- "www.食狮.com.cn" (* Returns: Ok "食狮.com.cn" *)
8686- Publicsuffix.registrable_domain psl "www.xn--85x722f.com.cn"
8787- (* Returns: Ok "xn--85x722f.com.cn" *)
8484+ Publicsuffix.registrable_domain psl
8585+ "www.食狮.com.cn" (* Returns: Ok "食狮.com.cn" *)
8686+ Publicsuffix.registrable_domain psl "www.xn--85x722f.com.cn"
8787+ (* Returns: Ok "xn--85x722f.com.cn" *)
8888 ]}
89899090 {1 Trailing Dots}
···9393 names) are preserved in the output:
94949595 {[
9696- Publicsuffix.public_suffix psl "example.com" (* Returns: Ok "com" *)
9797- Publicsuffix.public_suffix psl "example.com."
9898- (* Returns: Ok "com." *)
9696+ Publicsuffix.public_suffix psl "example.com" (* Returns: Ok "com" *)
9797+ Publicsuffix.public_suffix psl "example.com."
9898+ (* Returns: Ok "com." *)
9999 ]}
100100101101 {1 References}
···129129 | Private (** Domains submitted by private parties *)
130130131131type t
132132-(** A handle to the parsed Public Suffix List *)
132132+(** A handle to the parsed Public Suffix List. *)
133133+134134+val pp : Format.formatter -> t -> unit
135135+(** [pp fmt t] pretty-prints a summary of the PSL handle. *)
133136134137(** {1 Errors} *)
135138···158161 (** The domain is itself a public suffix and has no registrable domain *)
159162160163val pp_error : Format.formatter -> error -> unit
161161-(** Pretty-print an error *)
164164+(** Pretty-print an error. *)
162165163166val error_to_string : error -> string
164164-(** Convert an error to a human-readable string *)
167167+(** Convert an error to a human-readable string. *)
165168166169(** {1 Creation} *)
167170168168-val create : unit -> t
169169-(** Create a PSL instance using the embedded Public Suffix List data. The data
170170- is compiled into the library at build time. *)
171171+val v : unit -> t
172172+(** [v ()] creates a PSL instance using the embedded Public Suffix List data.
173173+ The data is compiled into the library at build time. *)
171174172175(** {1 Core Operations} *)
173176···202205 If the implicit [*] rule was used (no explicit rule matched), the section is
203206 [ICANN].
204207205205- @return [Ok (suffix, section)] or [Error e] on failure *)
208208+ @return [Ok (suffix, section)] or [Error e] on failure. *)
206209207210val registrable_domain : t -> string -> (string, error) result
208211(** [registrable_domain t domain] returns the registrable domain portion.
···225228 Examples:
226229 - [registrable_domain t "www.example.com"] returns [Ok "example.com"]
227230 - [registrable_domain t "example.com"] returns [Ok "example.com"]
228228- - [registrable_domain t "com"] returns [Error Domain_is_public_suffix] *)
231231+ - [registrable_domain t "com"] returns [Error Domain_is_public_suffix]. *)
229232230233val registrable_domain_with_section :
231234 t -> string -> (string * section, error) result
232235(** [registrable_domain_with_section t domain] is like {!registrable_domain} but
233236 also returns the section where the matching rule was found.
234237235235- @return [Ok (domain, section)] or [Error e] on failure *)
238238+ @return [Ok (domain, section)] or [Error e] on failure. *)
236239237240(** {1 Predicates} *)
238241···255258 Examples:
256259 - [is_registrable_domain t "example.com"] returns [Ok true]
257260 - [is_registrable_domain t "www.example.com"] returns [Ok false]
258258- - [is_registrable_domain t "com"] returns [Ok false] *)
261261+ - [is_registrable_domain t "com"] returns [Ok false]. *)
259262260263(** {1 Statistics} *)
261264262265val rule_count : t -> int
263263-(** Total number of rules in the embedded PSL *)
266266+(** Total number of rules in the embedded PSL. *)
264267265268val icann_rule_count : t -> int
266266-(** Number of ICANN section rules *)
269269+(** Number of ICANN section rules. *)
267270268271val private_rule_count : t -> int
269269-(** Number of private section rules *)
272272+(** Number of private section rules. *)
270273271274(** {1 Version Information} *)
272275···274277(** Version string from the embedded PSL data.
275278276279 Returns the version identifier from the Public Suffix List source file,
277277- typically in the format ["YYYY-MM-DD_HH-MM-SS_UTC"]. *)
280280+ typically in the format "YYYY-MM-DD_HH-MM-SS_UTC". *)
278281279282val commit : t -> string
280283(** Commit hash from the embedded PSL data.
+2-2
lib/publicsuffix_data.mli
···119119120120(** {1 Data Access} *)
121121122122-val get_root : unit -> trie_node
122122+val root : unit -> trie_node
123123(** Get the root of the suffix trie.
124124125125 The root node represents the starting point for all PSL lookups. Domain
126126 labels should be traversed in reverse order (TLD first) from this root.
127127128128- @return The root trie node containing all PSL rules *)
128128+ @return The root trie node containing all PSL rules. *)
129129130130(** {1 Statistics}
131131