Matrix protocol in OCaml, Eio specialised
at main 182 lines 6.8 kB view raw
1(** Room directory and alias operations. *) 2 3(* Alias resolution *) 4type alias_info = { 5 room_id : Matrix_proto.Id.Room_id.t; 6 servers : string list; 7} 8 9let alias_info_jsont = 10 Jsont.Object.( 11 map (fun room_id servers -> { room_id; servers }) 12 |> mem "room_id" Matrix_proto.Id.Room_id.jsont 13 |> mem "servers" (Jsont.list Jsont.string) ~dec_absent:[] 14 |> finish) 15 16let resolve_alias client ~alias = 17 let alias_str = Matrix_proto.Id.Room_alias.to_string alias in 18 let path = Printf.sprintf "/directory/room/%s" (Uri.pct_encode alias_str) in 19 match Client.get client ~path () with 20 | Error e -> Error e 21 | Ok body -> Client.decode_response alias_info_jsont body 22 23(* Create alias *) 24type create_alias_request = { 25 room_id : Matrix_proto.Id.Room_id.t; 26} [@@warning "-69"] 27 28let create_alias_request_jsont = 29 Jsont.Object.( 30 map (fun room_id -> { room_id }) 31 |> mem "room_id" Matrix_proto.Id.Room_id.jsont 32 |> finish) 33 34let create_alias client ~alias ~room_id = 35 let alias_str = Matrix_proto.Id.Room_alias.to_string alias in 36 let path = Printf.sprintf "/directory/room/%s" (Uri.pct_encode alias_str) in 37 let request = { room_id } in 38 match Client.encode_body create_alias_request_jsont request with 39 | Error e -> Error e 40 | Ok body -> 41 match Client.put client ~path ~body () with 42 | Error e -> Error e 43 | Ok _ -> Ok () 44 45(* Delete alias *) 46let delete_alias client ~alias = 47 let alias_str = Matrix_proto.Id.Room_alias.to_string alias in 48 let path = Printf.sprintf "/directory/room/%s" (Uri.pct_encode alias_str) in 49 match Client.delete client ~path () with 50 | Error e -> Error e 51 | Ok _ -> Ok () 52 53(* Room visibility *) 54type visibility = [ `Public | `Private ] 55 56type visibility_response = { 57 visibility : string; 58} 59 60let visibility_response_jsont = 61 Jsont.Object.( 62 map (fun visibility -> { visibility }) 63 |> mem "visibility" Jsont.string 64 |> finish) 65 66let get_visibility client ~room_id = 67 let room_id_str = Matrix_proto.Id.Room_id.to_string room_id in 68 let path = Printf.sprintf "/directory/list/room/%s" (Uri.pct_encode room_id_str) in 69 match Client.get client ~path () with 70 | Error e -> Error e 71 | Ok body -> 72 match Client.decode_response visibility_response_jsont body with 73 | Error e -> Error e 74 | Ok resp -> 75 match resp.visibility with 76 | "public" -> Ok `Public 77 | _ -> Ok `Private 78 79type set_visibility_request = { 80 visibility : string; 81} [@@warning "-69"] 82 83let set_visibility_request_jsont = 84 Jsont.Object.( 85 map (fun visibility -> { visibility }) 86 |> mem "visibility" Jsont.string 87 |> finish) 88 89let set_visibility client ~room_id ~visibility = 90 let room_id_str = Matrix_proto.Id.Room_id.to_string room_id in 91 let path = Printf.sprintf "/directory/list/room/%s" (Uri.pct_encode room_id_str) in 92 let vis_str = match visibility with `Public -> "public" | `Private -> "private" in 93 let request = { visibility = vis_str } in 94 match Client.encode_body set_visibility_request_jsont request with 95 | Error e -> Error e 96 | Ok body -> 97 match Client.put client ~path ~body () with 98 | Error e -> Error e 99 | Ok _ -> Ok () 100 101(* Room directory search *) 102type search_filter = { 103 generic_search_term : string option; 104 room_types : string list option; 105} 106 107type search_result = { 108 chunk : Rooms.public_room list; 109 next_batch : string option; 110 prev_batch : string option; 111 total_room_count_estimate : int option; 112} 113 114type search_request = { 115 filter : search_filter_request option; 116 limit : int option; 117 since : string option; 118} [@@warning "-69"] 119 120and search_filter_request = { 121 generic_search_term : string option; 122 room_types : string list option; 123} [@@warning "-69"] 124 125let search_filter_request_jsont = 126 Jsont.Object.( 127 map (fun generic_search_term room_types -> 128 { generic_search_term; room_types }) 129 |> opt_mem "generic_search_term" Jsont.string ~enc:(fun (t : search_filter_request) -> t.generic_search_term) 130 |> opt_mem "room_types" (Jsont.list Jsont.string) ~enc:(fun (t : search_filter_request) -> t.room_types) 131 |> finish) 132 133let search_request_jsont = 134 Jsont.Object.( 135 map (fun filter limit since -> { filter; limit; since }) 136 |> opt_mem "filter" search_filter_request_jsont ~enc:(fun (t : search_request) -> t.filter) 137 |> opt_mem "limit" Jsont.int ~enc:(fun (t : search_request) -> t.limit) 138 |> opt_mem "since" Jsont.string ~enc:(fun (t : search_request) -> t.since) 139 |> finish) 140 141(* Reuse public_room_jsont from Rooms - need to duplicate here *) 142let public_room_jsont : Rooms.public_room Jsont.t = 143 Jsont.Object.( 144 map (fun room_id name topic num_joined_members world_readable guest_can_join avatar_url canonical_alias -> 145 ({ room_id; name; topic; num_joined_members; world_readable; guest_can_join; avatar_url; canonical_alias } : Rooms.public_room)) 146 |> mem "room_id" Matrix_proto.Id.Room_id.jsont 147 |> opt_mem "name" Jsont.string ~enc:(fun (t : Rooms.public_room) -> t.name) 148 |> opt_mem "topic" Jsont.string ~enc:(fun (t : Rooms.public_room) -> t.topic) 149 |> mem "num_joined_members" Jsont.int ~dec_absent:0 ~enc:(fun (t : Rooms.public_room) -> t.num_joined_members) 150 |> mem "world_readable" Jsont.bool ~dec_absent:false ~enc:(fun (t : Rooms.public_room) -> t.world_readable) 151 |> mem "guest_can_join" Jsont.bool ~dec_absent:false ~enc:(fun (t : Rooms.public_room) -> t.guest_can_join) 152 |> opt_mem "avatar_url" Jsont.string ~enc:(fun (t : Rooms.public_room) -> t.avatar_url) 153 |> opt_mem "canonical_alias" Jsont.string ~enc:(fun (t : Rooms.public_room) -> t.canonical_alias) 154 |> finish) 155 156let search_result_jsont = 157 Jsont.Object.( 158 map (fun chunk next_batch prev_batch total_room_count_estimate -> 159 { chunk; next_batch; prev_batch; total_room_count_estimate }) 160 |> mem "chunk" (Jsont.list public_room_jsont) ~dec_absent:[] 161 |> opt_mem "next_batch" Jsont.string ~enc:(fun t -> t.next_batch) 162 |> opt_mem "prev_batch" Jsont.string ~enc:(fun t -> t.prev_batch) 163 |> opt_mem "total_room_count_estimate" Jsont.int ~enc:(fun t -> t.total_room_count_estimate) 164 |> finish) 165 166let search client ?server ?limit ?since ?(filter : search_filter option) () = 167 let path = "/publicRooms" in 168 let query = match server with 169 | Some s -> Some [("server", s)] 170 | None -> None 171 in 172 let filter_req : search_filter_request option = match filter with 173 | Some f -> Some { generic_search_term = f.generic_search_term; room_types = f.room_types } 174 | None -> None 175 in 176 let request = { filter = filter_req; limit; since } in 177 match Client.encode_body search_request_jsont request with 178 | Error e -> Error e 179 | Ok body -> 180 match Client.post client ~path ?query ~body () with 181 | Error e -> Error e 182 | Ok body -> Client.decode_response search_result_jsont body