My agentic slop goes here. Not intended for anyone else!
1(** JMAP Comparator for Sorting
2
3 Comparators define how to sort query results.
4 Multiple comparators can be chained for multi-level sorting.
5
6 Reference: RFC 8620 Section 5.5
7 Test files: test/data/core/request_query.json (sort field)
8*)
9
10(** Comparator type for sorting *)
11type t = {
12 property : string; (** Property name to sort by *)
13 is_ascending : bool; (** true = ascending, false = descending *)
14 collation : string option; (** Collation algorithm (optional) *)
15}
16
17(** Accessors *)
18let property t = t.property
19let is_ascending t = t.is_ascending
20let collation t = t.collation
21
22(** Constructor *)
23let v ?(is_ascending=true) ?collation ~property () =
24 { property; is_ascending; collation }
25
26(** Create a comparator *)
27let make ?(is_ascending=true) ?collation property =
28 { property; is_ascending; collation }
29
30(** Parse from JSON.
31 Expected JSON: {
32 "property": "name",
33 "isAscending": true,
34 "collation": "i;unicode-casemap"
35 }
36
37 Test files: test/data/core/request_query.json
38*)
39let of_json json =
40 match json with
41 | `O fields ->
42 let property = match List.assoc_opt "property" fields with
43 | Some (`String s) -> s
44 | Some _ -> raise (Jmap_error.Parse_error "Comparator property must be a string")
45 | None -> raise (Jmap_error.Parse_error "Comparator requires 'property' field")
46 in
47 let is_ascending = match List.assoc_opt "isAscending" fields with
48 | Some (`Bool b) -> b
49 | Some _ -> raise (Jmap_error.Parse_error "Comparator isAscending must be a boolean")
50 | None -> true (* Default: ascending *)
51 in
52 let collation = match List.assoc_opt "collation" fields with
53 | Some (`String s) -> Some s
54 | Some _ -> raise (Jmap_error.Parse_error "Comparator collation must be a string")
55 | None -> None
56 in
57 { property; is_ascending; collation }
58 | _ -> raise (Jmap_error.Parse_error "Comparator must be a JSON object")
59
60(** Convert to JSON *)
61let to_json t =
62 let fields = [
63 ("property", `String t.property);
64 ("isAscending", `Bool t.is_ascending);
65 ] in
66 let fields = match t.collation with
67 | Some c -> ("collation", `String c) :: fields
68 | None -> fields
69 in
70 `O fields