diff options
author | Clombrong <cromblong@egregore.fun> | 2025-07-02 00:37:15 +0200 |
---|---|---|
committer | Clombrong <cromblong@egregore.fun> | 2025-07-26 21:55:50 +0200 |
commit | 42a306a6be2663974fbd700713c78f7addac854d (patch) | |
tree | c3a0ea05c1b55f3dc5defbf60d664d39233e9063 | |
parent | 3f3903dd92643654ccdacafd6183f26537322d68 (diff) |
refactor(jid): add pos information to uchars type
-rw-r--r-- | lib/jid.ml | 45 |
1 files changed, 24 insertions, 21 deletions
@@ -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; |