aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClombrong <cromblong@egregore.fun>2025-07-02 00:37:15 +0200
committerClombrong <cromblong@egregore.fun>2025-07-26 21:55:50 +0200
commit42a306a6be2663974fbd700713c78f7addac854d (patch)
treec3a0ea05c1b55f3dc5defbf60d664d39233e9063
parent3f3903dd92643654ccdacafd6183f26537322d68 (diff)
refactor(jid): add pos information to uchars type
-rw-r--r--lib/jid.ml45
1 files changed, 24 insertions, 21 deletions
diff --git a/lib/jid.ml b/lib/jid.ml
index 9d9bb58..47de37d 100644
--- a/lib/jid.ml
+++ b/lib/jid.ml
@@ -6,7 +6,7 @@ type t = {
exception InvalidUTF8
-type uchars = Uchar.t list
+type uchars = (Uchar.t * int) list
let uchars_of_string s : uchars =
let open Uchar in
@@ -21,33 +21,36 @@ let uchars_of_string s : uchars =
else
let k = utf_decode_length c in
let u = utf_decode_uchar c in
- loop (u :: acc) (i + k)
+ loop ((u, i) :: acc) (i + k)
in loop [] 0
-let of_string (s : string) : t =
+let of_string (jid : string) : t =
let open List in
- let jid = uchars_of_string s in
- let rest, resourcepart =
- find_mapi (fun i c ->
+ let open String in
+ let u_jid = uchars_of_string jid in
+ let u_barejid, domain_end =
+ find_mapi (fun u_i (c, i) ->
if c = Uchar.of_char '/'
- then Some (take i jid, drop (i+1) jid |> string_of_uchars)
- else None) jid
- |> Option.fold ~none:(jid, None) ~some:(fun (rest, res) -> rest, Some res)
+ then Some (u_i, i)
+ else None) u_jid
+ |> Option.fold ~none:(u_jid, None) ~some:(fun (u_i, i) -> take u_i u_jid, Some i)
in
- let localpart, domainpart =
- rev rest
- |> find_mapi (fun i c ->
+ let domain_begin =
+ rev u_barejid
+ |> find_map (fun (c, i) ->
if c = Uchar.of_char '@'
- then let idx = length rest - i
- in Some (take (idx-1) rest |> string_of_uchars,
- drop idx rest |> string_of_uchars)
+ then Some (i+1)
else None)
- |> Option.fold ~none:(None, rest |> string_of_uchars) ~some:(fun (loc, dom) -> Some loc, dom)
- in {
- localpart;
- resourcepart;
- domainpart;
- }
+ in
+ let open Option in {
+ localpart = map (fun i -> sub jid 0 (i - 1)) domain_begin;
+ domainpart =
+ begin
+ let b = (value ~default:0 domain_begin) in
+ sub jid b ((value ~default:(length jid) domain_end) - b)
+ end;
+ resourcepart = map (fun i -> sub jid (i + 1) (length jid - i - 1)) domain_end;
+ }
let%expect_test {|A "bare JID"|} =
"juliet@example.com" |> of_string |> show |> print_string;