ActivityPub in OCaml using jsont/eio/requests
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

update to latest json/codec interfaces

+398 -408
+3 -3
apubt.opam
··· 2 2 opam-version: "2.0" 3 3 synopsis: "ActivityPub client library for OCaml with Eio" 4 4 description: 5 - "ActivityPub/ActivityStreams protocol implementation for OCaml. Provides typed representations of ActivityPub actors, activities, and objects with bidirectional JSON codecs using jsont. Includes an Eio-based HTTP client for federation with HTTP signature support." 5 + "ActivityPub/ActivityStreams protocol implementation for OCaml. Provides typed representations of ActivityPub actors, activities, and objects with bidirectional JSON codecs using nox-json. Includes an Eio-based HTTP client for federation with HTTP signature support." 6 6 maintainer: ["Anil Madhavapeddy <anil@recoil.org>"] 7 7 authors: ["Anil Madhavapeddy"] 8 8 license: "ISC" ··· 11 11 depends: [ 12 12 "dune" {>= "3.21"} 13 13 "ocaml" {>= "5.1.0"} 14 - "jsont" {>= "0.2.0"} 14 + "nox-json" 15 15 "bytesrw" 16 16 "eio" {>= "1.0"} 17 17 "eio_main" {>= "1.0"} ··· 21 21 "fmt" {>= "0.9.0"} 22 22 "ptime" 23 23 "uri" 24 - "x509" 24 + "nox-x509" 25 25 "odoc" {with-doc} 26 26 ] 27 27 build: [
+14 -17
bin/apub.ml
··· 43 43 try 44 44 let jrd = Apubt.Webfinger.lookup client account in 45 45 if json_output then begin 46 - match Jsont_bytesrw.encode_string Apubt.Proto.Webfinger.jsont jrd with 47 - | Ok s -> print_endline s 48 - | Error e -> Fmt.epr "JSON encoding error: %s@." e 46 + (try print_endline (Json.to_string Apubt.Proto.Webfinger.jsont jrd) 47 + with Json.Error e -> Fmt.epr "JSON encoding error: %a@." Json.Error.pp e) 49 48 end else begin 50 49 Fmt.pr "@[<v>"; 51 50 Fmt.pr "Subject: %s@," (Apubt.Proto.Webfinger.subject jrd); ··· 119 118 Apubt.Actor.fetch client (Uri.of_string uri_or_acct) 120 119 in 121 120 if json_output then begin 122 - match Jsont_bytesrw.encode_string Apubt.Proto.Actor.jsont actor with 123 - | Ok s -> print_endline s 124 - | Error e -> Fmt.epr "JSON encoding error: %s@." e 121 + (try print_endline (Json.to_string Apubt.Proto.Actor.jsont actor) 122 + with Json.Error e -> Fmt.epr "JSON encoding error: %a@." Json.Error.pp e) 125 123 end else begin 126 124 Fmt.pr "@[<v>"; 127 125 Fmt.pr "ID: %s@," (Uri.to_string (Apubt.Proto.Actor.id actor)); ··· 186 184 in 187 185 let outbox = Apubt.Actor.outbox client actor in 188 186 if json_output then begin 189 - match Jsont_bytesrw.encode_string Apubt.Proto.Activity_collection.jsont outbox with 190 - | Ok s -> print_endline s 191 - | Error e -> Fmt.epr "JSON encoding error: %s@." e 187 + (try print_endline (Json.to_string Apubt.Proto.Activity_collection.jsont outbox) 188 + with Json.Error e -> Fmt.epr "JSON encoding error: %a@." Json.Error.pp e) 192 189 end else begin 193 190 Fmt.pr "@[<v>"; 194 191 Fmt.pr "Outbox for: %s@," (Uri.to_string (Apubt.Proto.Actor.id actor)); ··· 376 373 (* Use Mastodon API if OAuth is available *) 377 374 match creds.auth with 378 375 | OAuth_auth { instance; token } -> 379 - let timeout_config = Requests.Timeout.create ~connect:timeout ~read:timeout () in 380 - let requests = Requests.create ~sw ~timeout:timeout_config env in 376 + let timeout_config = Requests.Timeout.v ~connect:timeout ~read:timeout () in 377 + let requests = Requests.v ~sw ~timeout:timeout_config env in 381 378 let visibility = if followers_only then Apub_mastodon_api.Private else Apub_mastodon_api.Public in 382 379 let spoiler_text = if sensitive then cw_summary else None in 383 380 (match Apub_mastodon_api.post_status requests ~instance ~token ~content ··· 448 445 (* Use Mastodon API if OAuth is available *) 449 446 match creds.auth with 450 447 | OAuth_auth { instance; token } -> 451 - let timeout_config = Requests.Timeout.create ~connect:timeout ~read:timeout () in 452 - let requests = Requests.create ~sw ~timeout:timeout_config env in 448 + let timeout_config = Requests.Timeout.v ~connect:timeout ~read:timeout () in 449 + let requests = Requests.v ~sw ~timeout:timeout_config env in 453 450 (* Look up the account first to get its ID *) 454 451 (match Apub_mastodon_api.lookup_account requests ~instance ~token ~acct:target with 455 452 | Ok account -> ··· 523 520 (* Use Mastodon API if OAuth is available *) 524 521 match creds.auth with 525 522 | OAuth_auth { instance; token } -> 526 - let timeout_config = Requests.Timeout.create ~connect:timeout ~read:timeout () in 527 - let requests = Requests.create ~sw ~timeout:timeout_config env in 523 + let timeout_config = Requests.Timeout.v ~connect:timeout ~read:timeout () in 524 + let requests = Requests.v ~sw ~timeout:timeout_config env in 528 525 (* Extract status ID from URL *) 529 526 (match Apub_mastodon_api.status_id_of_url object_uri with 530 527 | Some status_id -> ··· 587 584 (* Use Mastodon API if OAuth is available *) 588 585 match creds.auth with 589 586 | OAuth_auth { instance; token } -> 590 - let timeout_config = Requests.Timeout.create ~connect:timeout ~read:timeout () in 591 - let requests = Requests.create ~sw ~timeout:timeout_config env in 587 + let timeout_config = Requests.Timeout.v ~connect:timeout ~read:timeout () in 588 + let requests = Requests.v ~sw ~timeout:timeout_config env in 592 589 (* Extract status ID from URL *) 593 590 (match Apub_mastodon_api.status_id_of_url object_uri with 594 591 | Some status_id ->
+1 -1
bin/dune
··· 2 2 (name apub) 3 3 (public_name apub) 4 4 (package apubt) 5 - (libraries apubt apub_auth cmdliner eio_main fmt logs logs.cli logs.fmt fmt.cli fmt.tty requests)) 5 + (libraries apubt apub_auth cmdliner eio_main fmt logs logs.cli logs.fmt fmt.cli fmt.tty nox-json requests))
+3 -3
dune-project
··· 14 14 (description 15 15 "ActivityPub/ActivityStreams protocol implementation for OCaml. \ 16 16 Provides typed representations of ActivityPub actors, activities, \ 17 - and objects with bidirectional JSON codecs using jsont. Includes \ 17 + and objects with bidirectional JSON codecs using nox-json. Includes \ 18 18 an Eio-based HTTP client for federation with HTTP signature support.") 19 19 (depends 20 20 (ocaml (>= 5.1.0)) 21 - (jsont (>= 0.2.0)) 21 + nox-json 22 22 bytesrw 23 23 (eio (>= 1.0)) 24 24 (eio_main (>= 1.0)) ··· 28 28 (fmt (>= 0.9.0)) 29 29 ptime 30 30 uri 31 - x509 31 + nox-x509 32 32 (odoc :with-doc)))
+3 -3
lib/auth/apub_auth_cmd.ml
··· 110 110 Arg.(required & pos 0 (some string) None & info [] ~docv:"ACCOUNT" ~doc) 111 111 112 112 let login_action ~app_name ~account ~profile env = 113 - Mirage_crypto_rng_unix.use_default (); 113 + Crypto_rng_unix.use_default (); 114 114 let fs = env#fs in 115 115 (* Extract instance from account *) 116 116 let instance = match Apub_mastodon_oauth.instance_of_account account with ··· 122 122 Fmt.pr "Authenticating with %s...@." instance; 123 123 (* Create HTTP client *) 124 124 Eio.Switch.run @@ fun sw -> 125 - let timeout_config = Requests.Timeout.create ~connect:30.0 ~read:30.0 () in 126 - let requests = Requests.create ~sw ~timeout:timeout_config env in 125 + let timeout_config = Requests.Timeout.v ~connect:30.0 ~read:30.0 () in 126 + let requests = Requests.v ~sw ~timeout:timeout_config env in 127 127 (* Step 1: Register OAuth app *) 128 128 Fmt.pr "Registering OAuth app...@."; 129 129 let app = match Apub_mastodon_oauth.register_app requests ~instance with
+19 -23
lib/auth/apub_auth_session.ml
··· 17 17 } 18 18 19 19 let jsont = 20 - Jsont.Object.map ~kind:"Session" 20 + Json.Codec.Object.map ~kind:"Session" 21 21 (fun actor_uri key_id private_key_pem oauth_instance oauth_access_token 22 22 oauth_client_id oauth_client_secret created_at -> 23 23 { actor_uri; key_id; private_key_pem; oauth_instance; oauth_access_token; 24 24 oauth_client_id; oauth_client_secret; created_at }) 25 - |> Jsont.Object.mem "actor_uri" Jsont.string ~enc:(fun s -> s.actor_uri) 26 - |> Jsont.Object.opt_mem "key_id" Jsont.string ~enc:(fun s -> s.key_id) 27 - |> Jsont.Object.opt_mem "private_key_pem" Jsont.string 25 + |> Json.Codec.Object.member "actor_uri" Json.Codec.string ~enc:(fun s -> s.actor_uri) 26 + |> Json.Codec.Object.opt_member "key_id" Json.Codec.string ~enc:(fun s -> s.key_id) 27 + |> Json.Codec.Object.opt_member "private_key_pem" Json.Codec.string 28 28 ~enc:(fun s -> s.private_key_pem) 29 - |> Jsont.Object.opt_mem "oauth_instance" Jsont.string 29 + |> Json.Codec.Object.opt_member "oauth_instance" Json.Codec.string 30 30 ~enc:(fun s -> s.oauth_instance) 31 - |> Jsont.Object.opt_mem "oauth_access_token" Jsont.string 31 + |> Json.Codec.Object.opt_member "oauth_access_token" Json.Codec.string 32 32 ~enc:(fun s -> s.oauth_access_token) 33 - |> Jsont.Object.opt_mem "oauth_client_id" Jsont.string 33 + |> Json.Codec.Object.opt_member "oauth_client_id" Json.Codec.string 34 34 ~enc:(fun s -> s.oauth_client_id) 35 - |> Jsont.Object.opt_mem "oauth_client_secret" Jsont.string 35 + |> Json.Codec.Object.opt_member "oauth_client_secret" Json.Codec.string 36 36 ~enc:(fun s -> s.oauth_client_secret) 37 - |> Jsont.Object.mem "created_at" Jsont.string ~enc:(fun s -> s.created_at) 38 - |> Jsont.Object.finish 37 + |> Json.Codec.Object.member "created_at" Json.Codec.string ~enc:(fun s -> s.created_at) 38 + |> Json.Codec.Object.seal 39 39 40 40 (* App config stores the current profile *) 41 41 type app_config = { current_profile : string } 42 42 43 43 let app_config_jsont = 44 - Jsont.Object.map ~kind:"AppConfig" (fun current_profile -> 44 + Json.Codec.Object.map ~kind:"AppConfig" (fun current_profile -> 45 45 { current_profile }) 46 - |> Jsont.Object.mem "current_profile" Jsont.string ~enc:(fun c -> 46 + |> Json.Codec.Object.member "current_profile" Json.Codec.string ~enc:(fun c -> 47 47 c.current_profile) 48 - |> Jsont.Object.finish 48 + |> Json.Codec.Object.seal 49 49 50 50 let default_profile = "default" 51 51 ··· 88 88 let path = app_config_file fs ~app_name in 89 89 try 90 90 Eio.Path.load path 91 - |> Jsont_bytesrw.decode_string app_config_jsont 91 + |> Json.of_string app_config_jsont 92 92 |> Result.to_option 93 93 with Eio.Io (Eio.Fs.E (Eio.Fs.Not_found _), _) -> None 94 94 95 95 let save_app_config fs ~app_name config = 96 96 let path = app_config_file fs ~app_name in 97 - match 98 - Jsont_bytesrw.encode_string ~format:Jsont.Indent app_config_jsont config 99 - with 100 - | Ok content -> Eio.Path.save ~create:(`Or_truncate 0o600) path content 101 - | Error e -> failwith ("Failed to encode app config: " ^ e) 97 + let content = Json.to_string ~indent:2 app_config_jsont config in 98 + Eio.Path.save ~create:(`Or_truncate 0o600) path content 102 99 103 100 (* Get the current profile name *) 104 101 let get_current_profile fs ~app_name = ··· 141 138 in 142 139 let path = session_file fs ~app_name ?profile () in 143 140 try 144 - Eio.Path.load path |> Jsont_bytesrw.decode_string jsont |> Result.to_option 141 + Eio.Path.load path |> Json.of_string jsont |> Result.to_option 145 142 with Eio.Io (Eio.Fs.E (Eio.Fs.Not_found _), _) -> None 146 143 147 144 let save fs ~app_name ?profile session = ··· 151 148 | None -> Some (get_current_profile fs ~app_name) 152 149 in 153 150 let path = session_file fs ~app_name ?profile () in 154 - match Jsont_bytesrw.encode_string ~format:Jsont.Indent jsont session with 155 - | Ok content -> Eio.Path.save ~create:(`Or_truncate 0o600) path content 156 - | Error e -> failwith ("Failed to encode session: " ^ e) 151 + let content = Json.to_string ~indent:2 jsont session in 152 + Eio.Path.save ~create:(`Or_truncate 0o600) path content 157 153 158 154 let clear fs ~app_name ?profile () = 159 155 let profile =
+1 -1
lib/auth/apub_auth_session.mli
··· 67 67 - OAuth only: oauth_* fields 68 68 - Both: for hybrid authentication *) 69 69 70 - val jsont : t Jsont.t 70 + val jsont : t Json.codec 71 71 (** JSON codec for sessions. *) 72 72 73 73 (** {1 Session Creation} *)
+17 -17
lib/auth/apub_mastodon_api.ml
··· 25 25 } 26 26 27 27 let status_jsont = 28 - Jsont.Object.map ~kind:"MastodonStatus" 28 + Json.Codec.Object.map ~kind:"MastodonStatus" 29 29 (fun id uri url content created_at visibility -> 30 30 { id; uri; url; content; created_at; visibility }) 31 - |> Jsont.Object.mem "id" Jsont.string ~enc:(fun s -> s.id) 32 - |> Jsont.Object.mem "uri" Jsont.string ~enc:(fun s -> s.uri) 33 - |> Jsont.Object.opt_mem "url" Jsont.string ~enc:(fun s -> s.url) 34 - |> Jsont.Object.mem "content" Jsont.string ~enc:(fun s -> s.content) 35 - |> Jsont.Object.mem "created_at" Jsont.string ~enc:(fun s -> s.created_at) 36 - |> Jsont.Object.mem "visibility" Jsont.string ~enc:(fun s -> s.visibility) 37 - |> Jsont.Object.finish 31 + |> Json.Codec.Object.member "id" Json.Codec.string ~enc:(fun s -> s.id) 32 + |> Json.Codec.Object.member "uri" Json.Codec.string ~enc:(fun s -> s.uri) 33 + |> Json.Codec.Object.opt_member "url" Json.Codec.string ~enc:(fun s -> s.url) 34 + |> Json.Codec.Object.member "content" Json.Codec.string ~enc:(fun s -> s.content) 35 + |> Json.Codec.Object.member "created_at" Json.Codec.string ~enc:(fun s -> s.created_at) 36 + |> Json.Codec.Object.member "visibility" Json.Codec.string ~enc:(fun s -> s.visibility) 37 + |> Json.Codec.Object.seal 38 38 39 39 (** Relationship response (for follow/unfollow) *) 40 40 type relationship = { ··· 47 47 } 48 48 49 49 let relationship_jsont = 50 - Jsont.Object.map ~kind:"MastodonRelationship" 50 + Json.Codec.Object.map ~kind:"MastodonRelationship" 51 51 (fun id following followed_by blocking muting requested -> 52 52 { id; following; followed_by; blocking; muting; requested }) 53 - |> Jsont.Object.mem "id" Jsont.string ~enc:(fun r -> r.id) 54 - |> Jsont.Object.mem "following" Jsont.bool ~enc:(fun r -> r.following) 55 - |> Jsont.Object.mem "followed_by" Jsont.bool ~enc:(fun r -> r.followed_by) 56 - |> Jsont.Object.mem "blocking" Jsont.bool ~enc:(fun r -> r.blocking) 57 - |> Jsont.Object.mem "muting" Jsont.bool ~enc:(fun r -> r.muting) 58 - |> Jsont.Object.mem "requested" Jsont.bool ~enc:(fun r -> r.requested) 59 - |> Jsont.Object.finish 53 + |> Json.Codec.Object.member "id" Json.Codec.string ~enc:(fun r -> r.id) 54 + |> Json.Codec.Object.member "following" Json.Codec.bool ~enc:(fun r -> r.following) 55 + |> Json.Codec.Object.member "followed_by" Json.Codec.bool ~enc:(fun r -> r.followed_by) 56 + |> Json.Codec.Object.member "blocking" Json.Codec.bool ~enc:(fun r -> r.blocking) 57 + |> Json.Codec.Object.member "muting" Json.Codec.bool ~enc:(fun r -> r.muting) 58 + |> Json.Codec.Object.member "requested" Json.Codec.bool ~enc:(fun r -> r.requested) 59 + |> Json.Codec.Object.seal 60 60 61 61 (** Helper to create authenticated headers *) 62 62 let auth_headers token = ··· 171 171 let resp = Requests.get requests ~headers url in 172 172 match check_response resp with 173 173 | Error e -> Error e 174 - | Ok () -> Ok (Requests.Response.jsonv (Jsont.list Apub_mastodon_oauth.account_jsont) resp) 174 + | Ok () -> Ok (Requests.Response.jsonv (Json.Codec.list Apub_mastodon_oauth.account_jsont) resp) 175 175 176 176 (** Get a status by ID *) 177 177 let get_status requests ~instance ~token ~status_id =
+19 -19
lib/auth/apub_mastodon_oauth.ml
··· 24 24 } 25 25 26 26 let app_jsont = 27 - Jsont.Object.map ~kind:"MastodonApp" 27 + Json.Codec.Object.map ~kind:"MastodonApp" 28 28 (fun client_id client_secret vapid_key -> 29 29 { client_id; client_secret; vapid_key }) 30 - |> Jsont.Object.mem "client_id" Jsont.string ~enc:(fun a -> a.client_id) 31 - |> Jsont.Object.mem "client_secret" Jsont.string ~enc:(fun a -> a.client_secret) 32 - |> Jsont.Object.opt_mem "vapid_key" Jsont.string ~enc:(fun a -> a.vapid_key) 33 - |> Jsont.Object.finish 30 + |> Json.Codec.Object.member "client_id" Json.Codec.string ~enc:(fun a -> a.client_id) 31 + |> Json.Codec.Object.member "client_secret" Json.Codec.string ~enc:(fun a -> a.client_secret) 32 + |> Json.Codec.Object.opt_member "vapid_key" Json.Codec.string ~enc:(fun a -> a.vapid_key) 33 + |> Json.Codec.Object.seal 34 34 35 35 (** Token response *) 36 36 type token = { ··· 41 41 } 42 42 43 43 let token_jsont = 44 - Jsont.Object.map ~kind:"MastodonToken" 44 + Json.Codec.Object.map ~kind:"MastodonToken" 45 45 (fun access_token token_type scope created_at -> 46 46 { access_token; token_type; scope; created_at }) 47 - |> Jsont.Object.mem "access_token" Jsont.string ~enc:(fun t -> t.access_token) 48 - |> Jsont.Object.mem "token_type" Jsont.string ~enc:(fun t -> t.token_type) 49 - |> Jsont.Object.mem "scope" Jsont.string ~enc:(fun t -> t.scope) 50 - |> Jsont.Object.mem "created_at" Jsont.int ~enc:(fun t -> t.created_at) 51 - |> Jsont.Object.finish 47 + |> Json.Codec.Object.member "access_token" Json.Codec.string ~enc:(fun t -> t.access_token) 48 + |> Json.Codec.Object.member "token_type" Json.Codec.string ~enc:(fun t -> t.token_type) 49 + |> Json.Codec.Object.member "scope" Json.Codec.string ~enc:(fun t -> t.scope) 50 + |> Json.Codec.Object.member "created_at" Json.Codec.int ~enc:(fun t -> t.created_at) 51 + |> Json.Codec.Object.seal 52 52 53 53 (** Account (verify_credentials response) *) 54 54 type account = { ··· 60 60 } 61 61 62 62 let account_jsont = 63 - Jsont.Object.map ~kind:"MastodonAccount" 63 + Json.Codec.Object.map ~kind:"MastodonAccount" 64 64 (fun id username acct display_name url -> 65 65 { id; username; acct; display_name; url }) 66 - |> Jsont.Object.mem "id" Jsont.string ~enc:(fun a -> a.id) 67 - |> Jsont.Object.mem "username" Jsont.string ~enc:(fun a -> a.username) 68 - |> Jsont.Object.mem "acct" Jsont.string ~enc:(fun a -> a.acct) 69 - |> Jsont.Object.opt_mem "display_name" Jsont.string ~enc:(fun a -> a.display_name) 70 - |> Jsont.Object.mem "url" Jsont.string ~enc:(fun a -> a.url) 71 - |> Jsont.Object.finish 66 + |> Json.Codec.Object.member "id" Json.Codec.string ~enc:(fun a -> a.id) 67 + |> Json.Codec.Object.member "username" Json.Codec.string ~enc:(fun a -> a.username) 68 + |> Json.Codec.Object.member "acct" Json.Codec.string ~enc:(fun a -> a.acct) 69 + |> Json.Codec.Object.opt_member "display_name" Json.Codec.string ~enc:(fun a -> a.display_name) 70 + |> Json.Codec.Object.member "url" Json.Codec.string ~enc:(fun a -> a.url) 71 + |> Json.Codec.Object.seal 72 72 73 73 (** PKCE (Proof Key for Code Exchange) *) 74 74 module Pkce = struct 75 75 (** Generate a random code verifier (43-128 chars, URL-safe base64) *) 76 76 let generate_verifier () = 77 77 (* Generate 32 random bytes (will produce 43 base64 chars) *) 78 - let bytes = Mirage_crypto_rng.generate 32 in 78 + let bytes = Crypto_rng.generate 32 in 79 79 Base64.encode_string ~pad:false ~alphabet:Base64.uri_safe_alphabet bytes 80 80 81 81 (** Generate code challenge from verifier using SHA-256 *)
+4 -5
lib/auth/dune
··· 9 9 eio 10 10 eio_main 11 11 fmt 12 - jsont 13 - jsont.bytesrw 14 - mirage-crypto-rng 15 - mirage-crypto-rng.unix 12 + nox-json 13 + nox-crypto-rng 14 + nox-crypto-rng.unix 16 15 ptime.clock.os 17 16 requests 18 - x509)) 17 + nox-x509))
+14 -14
lib/client/apubt.ml
··· 95 95 "application/activity+json, application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" 96 96 97 97 let create ~sw ?signing ?(user_agent = "Apubt/0.1") ?(timeout = 30.0) env = 98 - let timeout_config = Requests.Timeout.create ~connect:timeout ~read:timeout () in 98 + let timeout_config = Requests.Timeout.v ~connect:timeout ~read:timeout () in 99 99 let default_headers = 100 100 Requests.Headers.empty 101 101 |> Requests.Headers.add `Accept activitypub_accept 102 102 |> Requests.Headers.add `User_agent user_agent 103 103 in 104 - let requests = Requests.create ~sw ~default_headers ~timeout:timeout_config env in 104 + let requests = Requests.v ~sw ~default_headers ~timeout:timeout_config env in 105 105 let clock = Eio.Stdenv.clock env in 106 106 T { requests; clock; signing; user_agent } 107 107 ··· 116 116 else if status = 429 then begin 117 117 let retry_after = 118 118 Requests.Response.headers resp 119 - |> Requests.Headers.get `Retry_after 119 + |> Requests.Headers.find `Retry_after 120 120 |> Option.map float_of_string 121 121 in 122 122 raise (E (Rate_limited retry_after)) ··· 171 171 172 172 (* Helper to encode JSON to string, raising on error *) 173 173 let encode_json_exn jsont value = 174 - match Jsont_bytesrw.encode_string jsont value with 175 - | Ok s -> s 176 - | Error msg -> raise (E (Json_error msg)) 174 + try Json.to_string jsont value 175 + with Json.Error err -> 176 + raise (E (Json_error (Format.asprintf "%a" Json.Error.pp err))) 177 177 178 178 let post (T t as client) uri body = 179 179 let url = Uri.to_string uri in 180 - let body_str = encode_json_exn Jsont.json body in 180 + let body_str = encode_json_exn Json.Codec.Value.t body in 181 181 let headers = 182 182 Requests.Headers.empty 183 183 |> Requests.Headers.set `Content_type "application/activity+json" ··· 319 319 } 320 320 321 321 let jsont = 322 - Jsont.Object.map ~kind:"WellKnownLink" 322 + Json.Codec.Object.map ~kind:"WellKnownLink" 323 323 (fun rel href -> { rel; href }) 324 - |> Jsont.Object.mem "rel" Jsont.string ~enc:(fun t -> t.rel) 325 - |> Jsont.Object.mem "href" Jsont.string ~enc:(fun t -> t.href) 326 - |> Jsont.Object.finish 324 + |> Json.Codec.Object.member "rel" Json.Codec.string ~enc:(fun t -> t.rel) 325 + |> Json.Codec.Object.member "href" Json.Codec.string ~enc:(fun t -> t.href) 326 + |> Json.Codec.Object.seal 327 327 end 328 328 329 329 module Well_known = struct ··· 332 332 } 333 333 334 334 let jsont = 335 - Jsont.Object.map ~kind:"WellKnownNodeinfo" 335 + Json.Codec.Object.map ~kind:"WellKnownNodeinfo" 336 336 (fun links -> { links }) 337 - |> Jsont.Object.mem "links" (Jsont.list Well_known_link.jsont) 337 + |> Json.Codec.Object.member "links" (Json.Codec.list Well_known_link.jsont) 338 338 ~enc:(fun t -> t.links) 339 - |> Jsont.Object.finish 339 + |> Json.Codec.Object.seal 340 340 end 341 341 342 342 let fetch (T t) ~host =
+9 -9
lib/client/apubt.mli
··· 499 499 t -> 500 500 ('a -> unit) -> 501 501 'a Proto.Collection.t -> 502 - 'a Jsont.t -> 502 + 'a Json.codec -> 503 503 unit 504 504 (** [iter client f collection item_jsont] iterates over all items in a collection, 505 505 automatically fetching subsequent pages. ··· 511 511 ('acc -> 'a -> 'acc) -> 512 512 'acc -> 513 513 'a Proto.Collection.t -> 514 - 'a Jsont.t -> 514 + 'a Json.codec -> 515 515 'acc 516 516 (** [fold client f init collection item_jsont] folds over all items in a collection, 517 517 automatically fetching subsequent pages. ··· 521 521 val to_list : 522 522 t -> 523 523 'a Proto.Collection.t -> 524 - 'a Jsont.t -> 524 + 'a Json.codec -> 525 525 'a list 526 526 (** [to_list client collection item_jsont] returns all items in a collection as a list. 527 527 ··· 532 532 val first_page : 533 533 t -> 534 534 'a Proto.Collection.t -> 535 - 'a Jsont.t -> 535 + 'a Json.codec -> 536 536 'a Proto.Collection_page.t option 537 537 (** [first_page client collection item_jsont] fetches the first page of a collection. 538 538 ··· 541 541 val next_page : 542 542 t -> 543 543 'a Proto.Collection_page.t -> 544 - 'a Jsont.t -> 544 + 'a Json.codec -> 545 545 'a Proto.Collection_page.t option 546 546 (** [next_page client page item_jsont] fetches the next page, if any. 547 547 ··· 552 552 553 553 (** Low-level HTTP operations with ActivityPub content negotiation. *) 554 554 module Http : sig 555 - val get : t -> Uri.t -> Jsont.json 555 + val get : t -> Uri.t -> Json.t 556 556 (** [get client uri] performs a GET request with ActivityPub Accept header. 557 557 558 558 @raise E on request failure *) 559 559 560 - val get_typed : t -> 'a Jsont.t -> Uri.t -> 'a 560 + val get_typed : t -> 'a Json.codec -> Uri.t -> 'a 561 561 (** [get_typed client jsont uri] performs a GET and decodes the response. 562 562 563 563 @raise E on request failure *) 564 564 565 - val post : t -> Uri.t -> Jsont.json -> unit 565 + val post : t -> Uri.t -> Json.t -> unit 566 566 (** [post client uri body] performs a signed POST request. 567 567 568 568 @raise E on request failure *) 569 569 570 - val post_typed : t -> 'a Jsont.t -> Uri.t -> 'a -> unit 570 + val post_typed : t -> 'a Json.codec -> Uri.t -> 'a -> unit 571 571 (** [post_typed client jsont uri value] encodes and POSTs a typed value. 572 572 573 573 @raise E on request failure *)
+1 -1
lib/client/dune
··· 1 1 (library 2 2 (name apubt) 3 3 (public_name apubt) 4 - (libraries apubt_proto eio jsont jsont.bytesrw ptime.clock.os requests webfinger x509)) 4 + (libraries apubt_proto eio nox-json ptime.clock.os requests webfinger nox-x509))
+253 -253
lib/proto/apubt_proto.ml
··· 14 14 type t 15 15 val v : string -> t 16 16 val to_string : t -> string 17 - val jsont : t Jsont.t 17 + val jsont : t Json.codec 18 18 end = struct 19 19 type t = string 20 20 let v s = s 21 21 let to_string t = t 22 - let jsont = Jsont.string |> Jsont.with_doc ~kind:"datetime" 22 + let jsont = Json.Codec.string |> Json.Codec.with_doc ~kind:"datetime" 23 23 end 24 24 25 25 (** JSON codec for [Uri.t] values. *) 26 - let uri_jsont : Uri.t Jsont.t = 27 - Jsont.string |> Jsont.map ~dec:Uri.of_string ~enc:Uri.to_string 26 + let uri_jsont : Uri.t Json.codec = 27 + Json.Codec.string |> Json.Codec.map ~dec:Uri.of_string ~enc:Uri.to_string 28 28 29 29 (** JSON-LD context. *) 30 30 module Context : sig 31 31 type t 32 32 val default : t 33 - val jsont : t Jsont.t 33 + val jsont : t Json.codec 34 34 end = struct 35 - type t = Jsont.json 35 + type t = Json.t 36 36 let default = 37 - Jsont.Json.string "https://www.w3.org/ns/activitystreams" 38 - let jsont = Jsont.json |> Jsont.with_doc ~kind:"@context" 37 + Json.Value.string "https://www.w3.org/ns/activitystreams" 38 + let jsont = Json.Codec.Value.t |> Json.Codec.with_doc ~kind:"@context" 39 39 end 40 40 41 41 (** Helper: JSON type that accepts either a single item or an array, normalizing to a list. 42 42 On encoding, always outputs an array for consistency. *) 43 - let one_or_many (item_jsont : 'a Jsont.t) : 'a list Jsont.t = 44 - let dec_array = Jsont.list item_jsont in 45 - let dec_single = Jsont.map item_jsont 43 + let one_or_many (item_jsont : 'a Json.codec) : 'a list Json.codec = 44 + let dec_array = Json.Codec.list item_jsont in 45 + let dec_single = Json.Codec.map item_jsont 46 46 ~dec:(fun x -> [x]) 47 47 ~enc:(fun _ -> assert false) (* never used for encoding *) 48 48 in 49 - Jsont.any ~kind:"one or many" 49 + Json.Codec.any ~kind:"one or many" 50 50 ~dec_array 51 51 ~dec_string:dec_single 52 52 ~dec_object:dec_single ··· 54 54 () 55 55 56 56 (** Helper: Nullable value - accepts null as None, value as Some value *) 57 - let nullable (jsont : 'a Jsont.t) : 'a option Jsont.t = 58 - let dec_null = Jsont.null None in 59 - let dec_value = Jsont.map jsont 57 + let nullable (jsont : 'a Json.codec) : 'a option Json.codec = 58 + let dec_null = Json.Codec.null None in 59 + let dec_value = Json.Codec.map jsont 60 60 ~dec:(fun v -> Some v) 61 61 ~enc:(function Some v -> v | None -> assert false) 62 62 in 63 - Jsont.any ~kind:"nullable" 63 + Json.Codec.any ~kind:"nullable" 64 64 ~dec_null 65 65 ~dec_string:dec_value 66 66 ~dec_number:dec_value ··· 75 75 (** Helper: URI that can also be an object with an id field. 76 76 This handles ActivityPub fields like 'replies' that can be either 77 77 a URI string or an inline Collection object. *) 78 - let uri_or_object_with_id : Uri.t Jsont.t = 78 + let uri_or_object_with_id : Uri.t Json.codec = 79 79 let id_jsont = 80 - Jsont.Object.map ~kind:"Object with id" (fun id -> id) 81 - |> Jsont.Object.mem "id" uri_jsont ~enc:Fun.id 82 - |> Jsont.Object.skip_unknown 83 - |> Jsont.Object.finish 80 + Json.Codec.Object.map ~kind:"Object with id" (fun id -> id) 81 + |> Json.Codec.Object.member "id" uri_jsont ~enc:Fun.id 82 + |> Json.Codec.Object.skip_unknown 83 + |> Json.Codec.Object.seal 84 84 in 85 - Jsont.any ~kind:"URI or object" 85 + Json.Codec.any ~kind:"URI or object" 86 86 ~dec_string:uri_jsont 87 87 ~dec_object:id_jsont 88 88 ~enc:(fun _ -> uri_jsont) ··· 114 114 val width : t -> int option 115 115 val preview : t -> Uri.t option 116 116 117 - val jsont : t Jsont.t 117 + val jsont : t Json.codec 118 118 end = struct 119 119 type t = { 120 120 href : Uri.t; ··· 138 138 let preview t = t.preview 139 139 140 140 let jsont = 141 - Jsont.Object.map ~kind:"Link" 141 + Json.Codec.Object.map ~kind:"Link" 142 142 (fun href media_type name hreflang height width preview -> 143 143 { href; media_type; name; hreflang; height; width; preview }) 144 - |> Jsont.Object.mem "href" uri_jsont ~enc:href 145 - |> Jsont.Object.opt_mem "mediaType" Jsont.string ~enc:media_type 146 - |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 147 - |> Jsont.Object.opt_mem "hreflang" Jsont.string ~enc:hreflang 148 - |> Jsont.Object.opt_mem "height" Jsont.int ~enc:height 149 - |> Jsont.Object.opt_mem "width" Jsont.int ~enc:width 150 - |> Jsont.Object.opt_mem "preview" uri_jsont ~enc:preview 151 - |> Jsont.Object.finish 144 + |> Json.Codec.Object.member "href" uri_jsont ~enc:href 145 + |> Json.Codec.Object.opt_member "mediaType" Json.Codec.string ~enc:media_type 146 + |> Json.Codec.Object.opt_member "name" Json.Codec.string ~enc:name 147 + |> Json.Codec.Object.opt_member "hreflang" Json.Codec.string ~enc:hreflang 148 + |> Json.Codec.Object.opt_member "height" Json.Codec.int ~enc:height 149 + |> Json.Codec.Object.opt_member "width" Json.Codec.int ~enc:width 150 + |> Json.Codec.Object.opt_member "preview" uri_jsont ~enc:preview 151 + |> Json.Codec.Object.seal 152 152 end 153 153 154 154 (** Reference that can be either a URI string or a Link object. *) ··· 159 159 160 160 val uri : Uri.t -> t 161 161 val link : Link.t -> t 162 - val jsont : t Jsont.t 162 + val jsont : t Json.codec 163 163 end = struct 164 164 type t = 165 165 | Uri of Uri.t ··· 169 169 let link l = Link l 170 170 171 171 let jsont = 172 - let dec_string = Jsont.map uri_jsont ~dec:(fun u -> Uri u) 172 + let dec_string = Json.Codec.map uri_jsont ~dec:(fun u -> Uri u) 173 173 ~enc:(function Uri u -> u | Link _ -> assert false) in 174 - let dec_object = Jsont.map Link.jsont ~dec:(fun l -> Link l) 174 + let dec_object = Json.Codec.map Link.jsont ~dec:(fun l -> Link l) 175 175 ~enc:(function Link l -> l | Uri _ -> assert false) in 176 - Jsont.any ~kind:"Link or URI" 176 + Json.Codec.any ~kind:"Link or URI" 177 177 ~dec_string ~dec_object 178 178 ~enc:(function 179 179 | Uri _ -> dec_string ··· 204 204 val width : t -> int option 205 205 val height : t -> int option 206 206 207 - val jsont : t Jsont.t 207 + val jsont : t Json.codec 208 208 end = struct 209 209 type t = { 210 210 id : Uri.t option; ··· 226 226 let height t = t.height 227 227 228 228 let jsont = 229 - Jsont.Object.map ~kind:"Image" 229 + Json.Codec.Object.map ~kind:"Image" 230 230 (fun id url name media_type width height -> 231 231 { id; url; name; media_type; width; height }) 232 - |> Jsont.Object.opt_mem "id" uri_jsont ~enc:id 233 - |> Jsont.Object.mem "url" Link_or_uri.jsont ~enc:url 234 - |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 235 - |> Jsont.Object.opt_mem "mediaType" Jsont.string ~enc:media_type 236 - |> Jsont.Object.opt_mem "width" Jsont.int ~enc:width 237 - |> Jsont.Object.opt_mem "height" Jsont.int ~enc:height 238 - |> Jsont.Object.finish 232 + |> Json.Codec.Object.opt_member "id" uri_jsont ~enc:id 233 + |> Json.Codec.Object.member "url" Link_or_uri.jsont ~enc:url 234 + |> Json.Codec.Object.opt_member "name" Json.Codec.string ~enc:name 235 + |> Json.Codec.Object.opt_member "mediaType" Json.Codec.string ~enc:media_type 236 + |> Json.Codec.Object.opt_member "width" Json.Codec.int ~enc:width 237 + |> Json.Codec.Object.opt_member "height" Json.Codec.int ~enc:height 238 + |> Json.Codec.Object.seal 239 239 end 240 240 241 241 (** Image reference - can be URI, Link, or full Image object. *) ··· 248 248 val uri : Uri.t -> t 249 249 val link : Link.t -> t 250 250 val image : Image.t -> t 251 - val jsont : t Jsont.t 251 + val jsont : t Json.codec 252 252 end = struct 253 253 type t = 254 254 | Uri of Uri.t ··· 261 261 262 262 let jsont = 263 263 (* For string case: URI *) 264 - let dec_string = Jsont.map uri_jsont ~dec:(fun u -> Uri u) 264 + let dec_string = Json.Codec.map uri_jsont ~dec:(fun u -> Uri u) 265 265 ~enc:(function Uri u -> u | _ -> assert false) in 266 266 (* For object case: either Link or Image *) 267 267 let dec_object = 268 268 (* Default: decode as Image if we can't determine type *) 269 - Jsont.map Image.jsont 269 + Json.Codec.map Image.jsont 270 270 ~dec:(fun i -> Image i) 271 271 ~enc:(function Image i -> i | _ -> assert false) 272 272 in 273 - Jsont.any ~kind:"Image reference" 273 + Json.Codec.any ~kind:"Image reference" 274 274 ~dec_string ~dec_object 275 275 ~enc:(function 276 276 | Uri _ -> dec_string ··· 299 299 val make : ?type_:string -> Uri.t -> t 300 300 val id : t -> Uri.t 301 301 val type_ : t -> string option 302 - val jsont : t Jsont.t 302 + val jsont : t Json.codec 303 303 end = struct 304 304 type t = { 305 305 id : Uri.t; ··· 311 311 let type_ t = t.type_ 312 312 313 313 let jsont = 314 - let dec_string = Jsont.map uri_jsont 314 + let dec_string = Json.Codec.map uri_jsont 315 315 ~dec:(fun u -> { id = u; type_ = None }) 316 316 ~enc:(fun t -> t.id) in 317 317 let dec_object = 318 - Jsont.Object.map ~kind:"Recipient" 318 + Json.Codec.Object.map ~kind:"Recipient" 319 319 (fun id type_ -> { id; type_ }) 320 - |> Jsont.Object.mem "id" uri_jsont ~enc:id 321 - |> Jsont.Object.opt_mem "type" Jsont.string ~enc:type_ 322 - |> Jsont.Object.finish 320 + |> Json.Codec.Object.member "id" uri_jsont ~enc:id 321 + |> Json.Codec.Object.opt_member "type" Json.Codec.string ~enc:type_ 322 + |> Json.Codec.Object.seal 323 323 in 324 - Jsont.any ~kind:"Recipient" 324 + Json.Codec.any ~kind:"Recipient" 325 325 ~dec_string ~dec_object 326 326 ~enc:(fun t -> 327 327 match t.type_ with ··· 352 352 val sign_client_key : t -> Uri.t option 353 353 val shared_inbox : t -> Uri.t option 354 354 355 - val jsont : t Jsont.t 355 + val jsont : t Json.codec 356 356 end = struct 357 357 type t = { 358 358 proxy_url : Uri.t option; ··· 376 376 let shared_inbox t = t.shared_inbox 377 377 378 378 let jsont = 379 - Jsont.Object.map ~kind:"Endpoints" 379 + Json.Codec.Object.map ~kind:"Endpoints" 380 380 (fun proxy_url oauth_authorization_endpoint oauth_token_endpoint 381 381 provide_client_key sign_client_key shared_inbox -> 382 382 { proxy_url; oauth_authorization_endpoint; oauth_token_endpoint; 383 383 provide_client_key; sign_client_key; shared_inbox }) 384 - |> Jsont.Object.opt_mem "proxyUrl" uri_jsont ~enc:proxy_url 385 - |> Jsont.Object.opt_mem "oauthAuthorizationEndpoint" uri_jsont 384 + |> Json.Codec.Object.opt_member "proxyUrl" uri_jsont ~enc:proxy_url 385 + |> Json.Codec.Object.opt_member "oauthAuthorizationEndpoint" uri_jsont 386 386 ~enc:oauth_authorization_endpoint 387 - |> Jsont.Object.opt_mem "oauthTokenEndpoint" uri_jsont 387 + |> Json.Codec.Object.opt_member "oauthTokenEndpoint" uri_jsont 388 388 ~enc:oauth_token_endpoint 389 - |> Jsont.Object.opt_mem "provideClientKey" uri_jsont ~enc:provide_client_key 390 - |> Jsont.Object.opt_mem "signClientKey" uri_jsont ~enc:sign_client_key 391 - |> Jsont.Object.opt_mem "sharedInbox" uri_jsont ~enc:shared_inbox 392 - |> Jsont.Object.finish 389 + |> Json.Codec.Object.opt_member "provideClientKey" uri_jsont ~enc:provide_client_key 390 + |> Json.Codec.Object.opt_member "signClientKey" uri_jsont ~enc:sign_client_key 391 + |> Json.Codec.Object.opt_member "sharedInbox" uri_jsont ~enc:shared_inbox 392 + |> Json.Codec.Object.seal 393 393 end 394 394 395 395 (** {1 Public Key} *) ··· 408 408 val owner : t -> Uri.t 409 409 val public_key_pem : t -> string 410 410 411 - val jsont : t Jsont.t 411 + val jsont : t Json.codec 412 412 end = struct 413 413 type t = { 414 414 id : Uri.t; ··· 424 424 let public_key_pem t = t.public_key_pem 425 425 426 426 let jsont = 427 - Jsont.Object.map ~kind:"PublicKey" 427 + Json.Codec.Object.map ~kind:"PublicKey" 428 428 (fun id owner public_key_pem -> { id; owner; public_key_pem }) 429 - |> Jsont.Object.mem "id" uri_jsont ~enc:id 430 - |> Jsont.Object.mem "owner" uri_jsont ~enc:owner 431 - |> Jsont.Object.mem "publicKeyPem" Jsont.string ~enc:public_key_pem 432 - |> Jsont.Object.finish 429 + |> Json.Codec.Object.member "id" uri_jsont ~enc:id 430 + |> Json.Codec.Object.member "owner" uri_jsont ~enc:owner 431 + |> Json.Codec.Object.member "publicKeyPem" Json.Codec.string ~enc:public_key_pem 432 + |> Json.Codec.Object.seal 433 433 end 434 434 435 435 (** {1 Actor Types} *) ··· 445 445 446 446 val to_string : t -> string 447 447 val of_string : string -> t option 448 - val jsont : t Jsont.t 448 + val jsont : t Json.codec 449 449 end = struct 450 450 type t = 451 451 | Person ··· 470 470 | _ -> None 471 471 472 472 let jsont = 473 - Jsont.enum ~kind:"ActorType" [ 473 + Json.Codec.enum ~kind:"ActorType" [ 474 474 "Person", Person; 475 475 "Service", Service; 476 476 "Organization", Organization; ··· 538 538 val featured : t -> Uri.t option 539 539 val featured_tags : t -> Uri.t option 540 540 541 - val jsont : t Jsont.t 541 + val jsont : t Json.codec 542 542 end = struct 543 543 type t = { 544 544 context : Context.t option; ··· 604 604 let featured_tags t = t.featured_tags 605 605 606 606 let jsont = 607 - Jsont.Object.map ~kind:"Actor" 607 + Json.Codec.Object.map ~kind:"Actor" 608 608 (fun context id type_ name preferred_username summary url inbox outbox 609 609 followers following liked streams endpoints public_key icon image 610 610 manually_approves_followers also_known_as discoverable suspended ··· 614 614 public_key; icon; image; manually_approves_followers; 615 615 also_known_as; discoverable; suspended; moved_to; featured; 616 616 featured_tags }) 617 - |> Jsont.Object.opt_mem "@context" Context.jsont ~enc:context 618 - |> Jsont.Object.mem "id" uri_jsont ~enc:id 619 - |> Jsont.Object.mem "type" Actor_type.jsont ~enc:type_ 620 - |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 621 - |> Jsont.Object.opt_mem "preferredUsername" Jsont.string 617 + |> Json.Codec.Object.opt_member "@context" Context.jsont ~enc:context 618 + |> Json.Codec.Object.member "id" uri_jsont ~enc:id 619 + |> Json.Codec.Object.member "type" Actor_type.jsont ~enc:type_ 620 + |> Json.Codec.Object.opt_member "name" Json.Codec.string ~enc:name 621 + |> Json.Codec.Object.opt_member "preferredUsername" Json.Codec.string 622 622 ~enc:preferred_username 623 - |> Jsont.Object.opt_mem "summary" Jsont.string ~enc:summary 624 - |> Jsont.Object.opt_mem "url" uri_jsont ~enc:url 625 - |> Jsont.Object.mem "inbox" uri_jsont ~enc:inbox 626 - |> Jsont.Object.mem "outbox" uri_jsont ~enc:outbox 627 - |> Jsont.Object.opt_mem "followers" uri_jsont ~enc:followers 628 - |> Jsont.Object.opt_mem "following" uri_jsont ~enc:following 629 - |> Jsont.Object.opt_mem "liked" uri_jsont ~enc:liked 630 - |> Jsont.Object.opt_mem "streams" (Jsont.list uri_jsont) ~enc:streams 631 - |> Jsont.Object.opt_mem "endpoints" Endpoints.jsont ~enc:endpoints 632 - |> Jsont.Object.opt_mem "publicKey" Public_key.jsont ~enc:public_key 633 - |> Jsont.Object.opt_mem "icon" (one_or_many Image_ref.jsont) ~enc:icon 634 - |> Jsont.Object.opt_mem "image" (one_or_many Image_ref.jsont) ~enc:image 635 - |> Jsont.Object.opt_mem "manuallyApprovesFollowers" Jsont.bool 623 + |> Json.Codec.Object.opt_member "summary" Json.Codec.string ~enc:summary 624 + |> Json.Codec.Object.opt_member "url" uri_jsont ~enc:url 625 + |> Json.Codec.Object.member "inbox" uri_jsont ~enc:inbox 626 + |> Json.Codec.Object.member "outbox" uri_jsont ~enc:outbox 627 + |> Json.Codec.Object.opt_member "followers" uri_jsont ~enc:followers 628 + |> Json.Codec.Object.opt_member "following" uri_jsont ~enc:following 629 + |> Json.Codec.Object.opt_member "liked" uri_jsont ~enc:liked 630 + |> Json.Codec.Object.opt_member "streams" (Json.Codec.list uri_jsont) ~enc:streams 631 + |> Json.Codec.Object.opt_member "endpoints" Endpoints.jsont ~enc:endpoints 632 + |> Json.Codec.Object.opt_member "publicKey" Public_key.jsont ~enc:public_key 633 + |> Json.Codec.Object.opt_member "icon" (one_or_many Image_ref.jsont) ~enc:icon 634 + |> Json.Codec.Object.opt_member "image" (one_or_many Image_ref.jsont) ~enc:image 635 + |> Json.Codec.Object.opt_member "manuallyApprovesFollowers" Json.Codec.bool 636 636 ~enc:manually_approves_followers 637 - |> Jsont.Object.opt_mem "alsoKnownAs" (one_or_many uri_jsont) 637 + |> Json.Codec.Object.opt_member "alsoKnownAs" (one_or_many uri_jsont) 638 638 ~enc:also_known_as 639 - |> Jsont.Object.opt_mem "discoverable" Jsont.bool ~enc:discoverable 640 - |> Jsont.Object.opt_mem "suspended" Jsont.bool ~enc:suspended 641 - |> Jsont.Object.opt_mem "movedTo" uri_jsont ~enc:moved_to 642 - |> Jsont.Object.opt_mem "featured" uri_jsont ~enc:featured 643 - |> Jsont.Object.opt_mem "featuredTags" uri_jsont ~enc:featured_tags 644 - |> Jsont.Object.finish 639 + |> Json.Codec.Object.opt_member "discoverable" Json.Codec.bool ~enc:discoverable 640 + |> Json.Codec.Object.opt_member "suspended" Json.Codec.bool ~enc:suspended 641 + |> Json.Codec.Object.opt_member "movedTo" uri_jsont ~enc:moved_to 642 + |> Json.Codec.Object.opt_member "featured" uri_jsont ~enc:featured 643 + |> Json.Codec.Object.opt_member "featuredTags" uri_jsont ~enc:featured_tags 644 + |> Json.Codec.Object.seal 645 645 end 646 646 647 647 (** Actor reference - can be URI or full Actor object. *) ··· 652 652 653 653 val uri : Uri.t -> t 654 654 val actor : Actor.t -> t 655 - val jsont : t Jsont.t 655 + val jsont : t Json.codec 656 656 end = struct 657 657 type t = 658 658 | Uri of Uri.t ··· 662 662 let actor a = Actor a 663 663 664 664 let jsont = 665 - let dec_string = Jsont.map uri_jsont 665 + let dec_string = Json.Codec.map uri_jsont 666 666 ~dec:(fun u -> Uri u) 667 667 ~enc:(function Uri u -> u | Actor _ -> assert false) in 668 - let dec_object = Jsont.map Actor.jsont 668 + let dec_object = Json.Codec.map Actor.jsont 669 669 ~dec:(fun a -> Actor a) 670 670 ~enc:(function Actor a -> a | Uri _ -> assert false) in 671 - Jsont.any ~kind:"Actor reference" 671 + Json.Codec.any ~kind:"Actor reference" 672 672 ~dec_string ~dec_object 673 673 ~enc:(function 674 674 | Uri _ -> dec_string ··· 697 697 698 698 val to_string : t -> string 699 699 val of_string : string -> t option 700 - val jsont : t Jsont.t 700 + val jsont : t Json.codec 701 701 end = struct 702 702 type t = 703 703 | Note ··· 746 746 | _ -> None 747 747 748 748 let jsont = 749 - Jsont.enum ~kind:"ObjectType" [ 749 + Json.Codec.enum ~kind:"ObjectType" [ 750 750 "Note", Note; 751 751 "Article", Article; 752 752 "Page", Page; ··· 841 841 val preview : t -> Link_or_uri.t option 842 842 (** [preview t] returns a preview of the object, typically a smaller version. *) 843 843 844 - val jsont : t Jsont.t 844 + val jsont : t Json.codec 845 845 (** JSON type for Objects. *) 846 846 end = struct 847 847 type t = { ··· 922 922 let preview t = t.preview 923 923 924 924 let jsont = 925 - Jsont.Object.map ~kind:"Object" 925 + Json.Codec.Object.map ~kind:"Object" 926 926 (fun context id type_ name summary content media_type url attributed_to 927 927 in_reply_to published updated deleted to_ cc bto bcc replies 928 928 attachment tag generator icon image start_time end_time duration ··· 932 932 to_; cc; bto; bcc; replies; attachment; tag; generator; 933 933 icon; image; start_time; end_time; duration; sensitive; 934 934 conversation; audience; location; preview }) 935 - |> Jsont.Object.opt_mem "@context" Context.jsont ~enc:context 936 - |> Jsont.Object.opt_mem "id" uri_jsont ~enc:id 937 - |> Jsont.Object.mem "type" Object_type.jsont ~enc:type_ 938 - |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 939 - |> Jsont.Object.mem "summary" (nullable Jsont.string) 935 + |> Json.Codec.Object.opt_member "@context" Context.jsont ~enc:context 936 + |> Json.Codec.Object.opt_member "id" uri_jsont ~enc:id 937 + |> Json.Codec.Object.member "type" Object_type.jsont ~enc:type_ 938 + |> Json.Codec.Object.opt_member "name" Json.Codec.string ~enc:name 939 + |> Json.Codec.Object.member "summary" (nullable Json.Codec.string) 940 940 ~dec_absent:None ~enc_omit:Option.is_none ~enc:summary 941 - |> Jsont.Object.mem "content" (nullable Jsont.string) 941 + |> Json.Codec.Object.member "content" (nullable Json.Codec.string) 942 942 ~dec_absent:None ~enc_omit:Option.is_none ~enc:content 943 - |> Jsont.Object.opt_mem "mediaType" Jsont.string ~enc:media_type 944 - |> Jsont.Object.opt_mem "url" (one_or_many Link_or_uri.jsont) ~enc:url 945 - |> Jsont.Object.opt_mem "attributedTo" Actor_ref.jsont ~enc:attributed_to 946 - |> Jsont.Object.mem "inReplyTo" (nullable uri_jsont) 943 + |> Json.Codec.Object.opt_member "mediaType" Json.Codec.string ~enc:media_type 944 + |> Json.Codec.Object.opt_member "url" (one_or_many Link_or_uri.jsont) ~enc:url 945 + |> Json.Codec.Object.opt_member "attributedTo" Actor_ref.jsont ~enc:attributed_to 946 + |> Json.Codec.Object.member "inReplyTo" (nullable uri_jsont) 947 947 ~dec_absent:None ~enc_omit:Option.is_none ~enc:in_reply_to 948 - |> Jsont.Object.opt_mem "published" Datetime.jsont ~enc:published 949 - |> Jsont.Object.opt_mem "updated" Datetime.jsont ~enc:updated 950 - |> Jsont.Object.opt_mem "deleted" Datetime.jsont ~enc:deleted 951 - |> Jsont.Object.opt_mem "to" (Jsont.list Recipient.jsont) ~enc:to_ 952 - |> Jsont.Object.opt_mem "cc" (Jsont.list Recipient.jsont) ~enc:cc 953 - |> Jsont.Object.opt_mem "bto" (Jsont.list Recipient.jsont) ~enc:bto 954 - |> Jsont.Object.opt_mem "bcc" (Jsont.list Recipient.jsont) ~enc:bcc 955 - |> Jsont.Object.opt_mem "replies" uri_or_object_with_id ~enc:replies 956 - |> Jsont.Object.opt_mem "attachment" (Jsont.list Link_or_uri.jsont) 948 + |> Json.Codec.Object.opt_member "published" Datetime.jsont ~enc:published 949 + |> Json.Codec.Object.opt_member "updated" Datetime.jsont ~enc:updated 950 + |> Json.Codec.Object.opt_member "deleted" Datetime.jsont ~enc:deleted 951 + |> Json.Codec.Object.opt_member "to" (Json.Codec.list Recipient.jsont) ~enc:to_ 952 + |> Json.Codec.Object.opt_member "cc" (Json.Codec.list Recipient.jsont) ~enc:cc 953 + |> Json.Codec.Object.opt_member "bto" (Json.Codec.list Recipient.jsont) ~enc:bto 954 + |> Json.Codec.Object.opt_member "bcc" (Json.Codec.list Recipient.jsont) ~enc:bcc 955 + |> Json.Codec.Object.opt_member "replies" uri_or_object_with_id ~enc:replies 956 + |> Json.Codec.Object.opt_member "attachment" (Json.Codec.list Link_or_uri.jsont) 957 957 ~enc:attachment 958 - |> Jsont.Object.opt_mem "tag" (Jsont.list Link_or_uri.jsont) ~enc:tag 959 - |> Jsont.Object.opt_mem "generator" uri_jsont ~enc:generator 960 - |> Jsont.Object.opt_mem "icon" (one_or_many Image_ref.jsont) ~enc:icon 961 - |> Jsont.Object.opt_mem "image" (one_or_many Image_ref.jsont) ~enc:image 962 - |> Jsont.Object.opt_mem "startTime" Datetime.jsont ~enc:start_time 963 - |> Jsont.Object.opt_mem "endTime" Datetime.jsont ~enc:end_time 964 - |> Jsont.Object.opt_mem "duration" Jsont.string ~enc:duration 965 - |> Jsont.Object.opt_mem "sensitive" Jsont.bool ~enc:sensitive 966 - |> Jsont.Object.opt_mem "conversation" uri_jsont ~enc:conversation 967 - |> Jsont.Object.opt_mem "audience" (one_or_many Recipient.jsont) ~enc:audience 968 - |> Jsont.Object.opt_mem "location" Link_or_uri.jsont ~enc:location 969 - |> Jsont.Object.opt_mem "preview" Link_or_uri.jsont ~enc:preview 970 - |> Jsont.Object.finish 958 + |> Json.Codec.Object.opt_member "tag" (Json.Codec.list Link_or_uri.jsont) ~enc:tag 959 + |> Json.Codec.Object.opt_member "generator" uri_jsont ~enc:generator 960 + |> Json.Codec.Object.opt_member "icon" (one_or_many Image_ref.jsont) ~enc:icon 961 + |> Json.Codec.Object.opt_member "image" (one_or_many Image_ref.jsont) ~enc:image 962 + |> Json.Codec.Object.opt_member "startTime" Datetime.jsont ~enc:start_time 963 + |> Json.Codec.Object.opt_member "endTime" Datetime.jsont ~enc:end_time 964 + |> Json.Codec.Object.opt_member "duration" Json.Codec.string ~enc:duration 965 + |> Json.Codec.Object.opt_member "sensitive" Json.Codec.bool ~enc:sensitive 966 + |> Json.Codec.Object.opt_member "conversation" uri_jsont ~enc:conversation 967 + |> Json.Codec.Object.opt_member "audience" (one_or_many Recipient.jsont) ~enc:audience 968 + |> Json.Codec.Object.opt_member "location" Link_or_uri.jsont ~enc:location 969 + |> Json.Codec.Object.opt_member "preview" Link_or_uri.jsont ~enc:preview 970 + |> Json.Codec.Object.seal 971 971 end 972 972 973 973 (** Object reference - can be URI or full Object. *) ··· 978 978 979 979 val uri : Uri.t -> t 980 980 val obj : Object.t -> t 981 - val jsont : t Jsont.t 981 + val jsont : t Json.codec 982 982 end = struct 983 983 type t = 984 984 | Uri of Uri.t ··· 988 988 let obj o = Object o 989 989 990 990 let jsont = 991 - let dec_string = Jsont.map uri_jsont 991 + let dec_string = Json.Codec.map uri_jsont 992 992 ~dec:(fun u -> Uri u) 993 993 ~enc:(function Uri u -> u | Object _ -> assert false) in 994 - let dec_object = Jsont.map Object.jsont 994 + let dec_object = Json.Codec.map Object.jsont 995 995 ~dec:(fun o -> Object o) 996 996 ~enc:(function Object o -> o | Uri _ -> assert false) in 997 - Jsont.any ~kind:"Object reference" 997 + Json.Codec.any ~kind:"Object reference" 998 998 ~dec_string ~dec_object 999 999 ~enc:(function 1000 1000 | Uri _ -> dec_string ··· 1037 1037 1038 1038 val to_string : t -> string 1039 1039 val of_string : string -> t option 1040 - val jsont : t Jsont.t 1040 + val jsont : t Json.codec 1041 1041 end = struct 1042 1042 type t = 1043 1043 | Create ··· 1128 1128 | _ -> None 1129 1129 1130 1130 let jsont = 1131 - Jsont.enum ~kind:"ActivityType" [ 1131 + Json.Codec.enum ~kind:"ActivityType" [ 1132 1132 "Create", Create; 1133 1133 "Update", Update; 1134 1134 "Delete", Delete; ··· 1219 1219 val closed : t -> Datetime.t option 1220 1220 (** [closed t] returns when the poll was closed, for Question activities. *) 1221 1221 1222 - val jsont : t Jsont.t 1222 + val jsont : t Json.codec 1223 1223 (** JSON type for Activities. *) 1224 1224 end = struct 1225 1225 type t = { ··· 1272 1272 let closed t = t.closed 1273 1273 1274 1274 let jsont = 1275 - Jsont.Object.map ~kind:"Activity" 1275 + Json.Codec.Object.map ~kind:"Activity" 1276 1276 (fun context id type_ actor object_ target result origin instrument 1277 1277 to_ cc bto bcc published updated summary one_of any_of closed -> 1278 1278 { context; id; type_; actor; object_; target; result; origin; 1279 1279 instrument; to_; cc; bto; bcc; published; updated; summary; 1280 1280 one_of; any_of; closed }) 1281 - |> Jsont.Object.opt_mem "@context" Context.jsont ~enc:context 1282 - |> Jsont.Object.opt_mem "id" uri_jsont ~enc:id 1283 - |> Jsont.Object.mem "type" Activity_type.jsont ~enc:type_ 1284 - |> Jsont.Object.mem "actor" Actor_ref.jsont ~enc:actor 1285 - |> Jsont.Object.opt_mem "object" Object_ref.jsont ~enc:object_ 1286 - |> Jsont.Object.opt_mem "target" Object_ref.jsont ~enc:target 1287 - |> Jsont.Object.opt_mem "result" Object_ref.jsont ~enc:result 1288 - |> Jsont.Object.opt_mem "origin" Object_ref.jsont ~enc:origin 1289 - |> Jsont.Object.opt_mem "instrument" Object_ref.jsont ~enc:instrument 1290 - |> Jsont.Object.opt_mem "to" (Jsont.list Recipient.jsont) ~enc:to_ 1291 - |> Jsont.Object.opt_mem "cc" (Jsont.list Recipient.jsont) ~enc:cc 1292 - |> Jsont.Object.opt_mem "bto" (Jsont.list Recipient.jsont) ~enc:bto 1293 - |> Jsont.Object.opt_mem "bcc" (Jsont.list Recipient.jsont) ~enc:bcc 1294 - |> Jsont.Object.opt_mem "published" Datetime.jsont ~enc:published 1295 - |> Jsont.Object.opt_mem "updated" Datetime.jsont ~enc:updated 1296 - |> Jsont.Object.opt_mem "summary" Jsont.string ~enc:summary 1297 - |> Jsont.Object.opt_mem "oneOf" (Jsont.list Object_ref.jsont) ~enc:one_of 1298 - |> Jsont.Object.opt_mem "anyOf" (Jsont.list Object_ref.jsont) ~enc:any_of 1299 - |> Jsont.Object.opt_mem "closed" Datetime.jsont ~enc:closed 1300 - |> Jsont.Object.finish 1281 + |> Json.Codec.Object.opt_member "@context" Context.jsont ~enc:context 1282 + |> Json.Codec.Object.opt_member "id" uri_jsont ~enc:id 1283 + |> Json.Codec.Object.member "type" Activity_type.jsont ~enc:type_ 1284 + |> Json.Codec.Object.member "actor" Actor_ref.jsont ~enc:actor 1285 + |> Json.Codec.Object.opt_member "object" Object_ref.jsont ~enc:object_ 1286 + |> Json.Codec.Object.opt_member "target" Object_ref.jsont ~enc:target 1287 + |> Json.Codec.Object.opt_member "result" Object_ref.jsont ~enc:result 1288 + |> Json.Codec.Object.opt_member "origin" Object_ref.jsont ~enc:origin 1289 + |> Json.Codec.Object.opt_member "instrument" Object_ref.jsont ~enc:instrument 1290 + |> Json.Codec.Object.opt_member "to" (Json.Codec.list Recipient.jsont) ~enc:to_ 1291 + |> Json.Codec.Object.opt_member "cc" (Json.Codec.list Recipient.jsont) ~enc:cc 1292 + |> Json.Codec.Object.opt_member "bto" (Json.Codec.list Recipient.jsont) ~enc:bto 1293 + |> Json.Codec.Object.opt_member "bcc" (Json.Codec.list Recipient.jsont) ~enc:bcc 1294 + |> Json.Codec.Object.opt_member "published" Datetime.jsont ~enc:published 1295 + |> Json.Codec.Object.opt_member "updated" Datetime.jsont ~enc:updated 1296 + |> Json.Codec.Object.opt_member "summary" Json.Codec.string ~enc:summary 1297 + |> Json.Codec.Object.opt_member "oneOf" (Json.Codec.list Object_ref.jsont) ~enc:one_of 1298 + |> Json.Codec.Object.opt_member "anyOf" (Json.Codec.list Object_ref.jsont) ~enc:any_of 1299 + |> Json.Codec.Object.opt_member "closed" Datetime.jsont ~enc:closed 1300 + |> Json.Codec.Object.seal 1301 1301 end 1302 1302 1303 1303 (** Activity reference - can be URI or full Activity. *) ··· 1308 1308 1309 1309 val uri : Uri.t -> t 1310 1310 val activity : Activity.t -> t 1311 - val jsont : t Jsont.t 1311 + val jsont : t Json.codec 1312 1312 end = struct 1313 1313 type t = 1314 1314 | Uri of Uri.t ··· 1318 1318 let activity a = Activity a 1319 1319 1320 1320 let jsont = 1321 - let dec_string = Jsont.map uri_jsont 1321 + let dec_string = Json.Codec.map uri_jsont 1322 1322 ~dec:(fun u -> Uri u) 1323 1323 ~enc:(function Uri u -> u | Activity _ -> assert false) in 1324 - let dec_object = Jsont.map Activity.jsont 1324 + let dec_object = Json.Codec.map Activity.jsont 1325 1325 ~dec:(fun a -> Activity a) 1326 1326 ~enc:(function Activity a -> a | Uri _ -> assert false) in 1327 - Jsont.any ~kind:"Activity reference" 1327 + Json.Codec.any ~kind:"Activity reference" 1328 1328 ~dec_string ~dec_object 1329 1329 ~enc:(function 1330 1330 | Uri _ -> dec_string ··· 1359 1359 val items : 'a t -> 'a list option 1360 1360 val ordered : 'a t -> bool 1361 1361 1362 - val jsont : 'a Jsont.t -> 'a t Jsont.t 1362 + val jsont : 'a Json.codec -> 'a t Json.codec 1363 1363 end = struct 1364 1364 type 'a t = { 1365 1365 context : Context.t option; ··· 1386 1386 1387 1387 let jsont item_jsont = 1388 1388 let type_jsont = 1389 - Jsont.enum ~kind:"CollectionType" [ 1389 + Json.Codec.enum ~kind:"CollectionType" [ 1390 1390 "Collection", false; 1391 1391 "OrderedCollection", true; 1392 1392 ] 1393 1393 in 1394 - let list_jsont = Jsont.list item_jsont in 1395 - Jsont.Object.map ~kind:"Collection" 1394 + let list_jsont = Json.Codec.list item_jsont in 1395 + Json.Codec.Object.map ~kind:"Collection" 1396 1396 (fun context id ordered total_items current first last items ordered_items -> 1397 1397 let items = match items, ordered_items with 1398 1398 | Some i, _ -> Some i ··· 1400 1400 | None, None -> None 1401 1401 in 1402 1402 { context; id; total_items; current; first; last; items; ordered }) 1403 - |> Jsont.Object.opt_mem "@context" Context.jsont ~enc:context 1404 - |> Jsont.Object.opt_mem "id" uri_jsont ~enc:id 1405 - |> Jsont.Object.mem "type" type_jsont ~enc:ordered 1406 - |> Jsont.Object.opt_mem "totalItems" Jsont.int ~enc:total_items 1407 - |> Jsont.Object.opt_mem "current" uri_jsont ~enc:current 1408 - |> Jsont.Object.opt_mem "first" uri_jsont ~enc:first 1409 - |> Jsont.Object.opt_mem "last" uri_jsont ~enc:last 1410 - |> Jsont.Object.opt_mem "items" list_jsont 1403 + |> Json.Codec.Object.opt_member "@context" Context.jsont ~enc:context 1404 + |> Json.Codec.Object.opt_member "id" uri_jsont ~enc:id 1405 + |> Json.Codec.Object.member "type" type_jsont ~enc:ordered 1406 + |> Json.Codec.Object.opt_member "totalItems" Json.Codec.int ~enc:total_items 1407 + |> Json.Codec.Object.opt_member "current" uri_jsont ~enc:current 1408 + |> Json.Codec.Object.opt_member "first" uri_jsont ~enc:first 1409 + |> Json.Codec.Object.opt_member "last" uri_jsont ~enc:last 1410 + |> Json.Codec.Object.opt_member "items" list_jsont 1411 1411 ~enc:(fun t -> if t.ordered then None else t.items) 1412 - |> Jsont.Object.opt_mem "orderedItems" list_jsont 1412 + |> Json.Codec.Object.opt_member "orderedItems" list_jsont 1413 1413 ~enc:(fun t -> if t.ordered then t.items else None) 1414 - |> Jsont.Object.finish 1414 + |> Json.Codec.Object.seal 1415 1415 end 1416 1416 1417 1417 (** {1 Collection Page} *) ··· 1447 1447 val items : 'a t -> 'a list option 1448 1448 val ordered : 'a t -> bool 1449 1449 1450 - val jsont : 'a Jsont.t -> 'a t Jsont.t 1450 + val jsont : 'a Json.codec -> 'a t Json.codec 1451 1451 end = struct 1452 1452 type 'a t = { 1453 1453 context : Context.t option; ··· 1482 1482 1483 1483 let jsont item_jsont = 1484 1484 let type_jsont = 1485 - Jsont.enum ~kind:"CollectionPageType" [ 1485 + Json.Codec.enum ~kind:"CollectionPageType" [ 1486 1486 "CollectionPage", false; 1487 1487 "OrderedCollectionPage", true; 1488 1488 ] 1489 1489 in 1490 - let list_jsont = Jsont.list item_jsont in 1491 - Jsont.Object.map ~kind:"CollectionPage" 1490 + let list_jsont = Json.Codec.list item_jsont in 1491 + Json.Codec.Object.map ~kind:"CollectionPage" 1492 1492 (fun context id ordered total_items current first last prev next 1493 1493 part_of items ordered_items -> 1494 1494 let items = match items, ordered_items with ··· 1498 1498 in 1499 1499 { context; id; total_items; current; first; last; prev; next; 1500 1500 part_of; items; ordered }) 1501 - |> Jsont.Object.opt_mem "@context" Context.jsont ~enc:context 1502 - |> Jsont.Object.opt_mem "id" uri_jsont ~enc:id 1503 - |> Jsont.Object.mem "type" type_jsont ~enc:ordered 1504 - |> Jsont.Object.opt_mem "totalItems" Jsont.int ~enc:total_items 1505 - |> Jsont.Object.opt_mem "current" uri_jsont ~enc:current 1506 - |> Jsont.Object.opt_mem "first" uri_jsont ~enc:first 1507 - |> Jsont.Object.opt_mem "last" uri_jsont ~enc:last 1508 - |> Jsont.Object.opt_mem "prev" uri_jsont ~enc:prev 1509 - |> Jsont.Object.opt_mem "next" uri_jsont ~enc:next 1510 - |> Jsont.Object.opt_mem "partOf" uri_jsont ~enc:part_of 1511 - |> Jsont.Object.opt_mem "items" list_jsont 1501 + |> Json.Codec.Object.opt_member "@context" Context.jsont ~enc:context 1502 + |> Json.Codec.Object.opt_member "id" uri_jsont ~enc:id 1503 + |> Json.Codec.Object.member "type" type_jsont ~enc:ordered 1504 + |> Json.Codec.Object.opt_member "totalItems" Json.Codec.int ~enc:total_items 1505 + |> Json.Codec.Object.opt_member "current" uri_jsont ~enc:current 1506 + |> Json.Codec.Object.opt_member "first" uri_jsont ~enc:first 1507 + |> Json.Codec.Object.opt_member "last" uri_jsont ~enc:last 1508 + |> Json.Codec.Object.opt_member "prev" uri_jsont ~enc:prev 1509 + |> Json.Codec.Object.opt_member "next" uri_jsont ~enc:next 1510 + |> Json.Codec.Object.opt_member "partOf" uri_jsont ~enc:part_of 1511 + |> Json.Codec.Object.opt_member "items" list_jsont 1512 1512 ~enc:(fun t -> if t.ordered then None else t.items) 1513 - |> Jsont.Object.opt_mem "orderedItems" list_jsont 1513 + |> Json.Codec.Object.opt_member "orderedItems" list_jsont 1514 1514 ~enc:(fun t -> if t.ordered then t.items else None) 1515 - |> Jsont.Object.finish 1515 + |> Json.Codec.Object.seal 1516 1516 end 1517 1517 1518 1518 (** {1 Convenience type aliases} *) ··· 1520 1520 (** Activity collection. *) 1521 1521 module Activity_collection : sig 1522 1522 type t = Activity.t Collection.t 1523 - val jsont : t Jsont.t 1523 + val jsont : t Json.codec 1524 1524 end = struct 1525 1525 type t = Activity.t Collection.t 1526 1526 let jsont = Collection.jsont Activity.jsont ··· 1529 1529 (** Object collection. *) 1530 1530 module Object_collection : sig 1531 1531 type t = Object.t Collection.t 1532 - val jsont : t Jsont.t 1532 + val jsont : t Json.codec 1533 1533 end = struct 1534 1534 type t = Object.t Collection.t 1535 1535 let jsont = Collection.jsont Object.jsont ··· 1538 1538 (** Activity collection page. *) 1539 1539 module Activity_collection_page : sig 1540 1540 type t = Activity.t Collection_page.t 1541 - val jsont : t Jsont.t 1541 + val jsont : t Json.codec 1542 1542 end = struct 1543 1543 type t = Activity.t Collection_page.t 1544 1544 let jsont = Collection_page.jsont Activity.jsont ··· 1547 1547 (** Object collection page. *) 1548 1548 module Object_collection_page : sig 1549 1549 type t = Object.t Collection_page.t 1550 - val jsont : t Jsont.t 1550 + val jsont : t Json.codec 1551 1551 end = struct 1552 1552 type t = Object.t Collection_page.t 1553 1553 let jsont = Collection_page.jsont Object.jsont ··· 1574 1574 val href : t -> Uri.t option 1575 1575 val template : t -> string option 1576 1576 1577 - val jsont : t Jsont.t 1577 + val jsont : t Json.codec 1578 1578 end 1579 1579 1580 1580 (** The Webfinger JRD response. *) ··· 1592 1592 val properties : t -> (string * string) list option 1593 1593 val links : t -> Jrd_link.t list option 1594 1594 1595 - val jsont : t Jsont.t 1595 + val jsont : t Json.codec 1596 1596 end = struct 1597 1597 module Jrd_link = struct 1598 1598 type t = { ··· 1611 1611 let template t = t.template 1612 1612 1613 1613 let jsont = 1614 - Jsont.Object.map ~kind:"JrdLink" 1614 + Json.Codec.Object.map ~kind:"JrdLink" 1615 1615 (fun rel type_ href template -> { rel; type_; href; template }) 1616 - |> Jsont.Object.mem "rel" Jsont.string ~enc:rel 1617 - |> Jsont.Object.opt_mem "type" Jsont.string ~enc:type_ 1618 - |> Jsont.Object.opt_mem "href" uri_jsont ~enc:href 1619 - |> Jsont.Object.opt_mem "template" Jsont.string ~enc:template 1620 - |> Jsont.Object.finish 1616 + |> Json.Codec.Object.member "rel" Json.Codec.string ~enc:rel 1617 + |> Json.Codec.Object.opt_member "type" Json.Codec.string ~enc:type_ 1618 + |> Json.Codec.Object.opt_member "href" uri_jsont ~enc:href 1619 + |> Json.Codec.Object.opt_member "template" Json.Codec.string ~enc:template 1620 + |> Json.Codec.Object.seal 1621 1621 end 1622 1622 1623 1623 type t = { ··· 1638 1638 module String_map = Map.Make(String) 1639 1639 1640 1640 let properties_jsont = 1641 - Jsont.Object.as_string_map Jsont.string 1642 - |> Jsont.map 1641 + Json.Codec.Object.as_string_map Json.Codec.string 1642 + |> Json.Codec.map 1643 1643 ~dec:(fun m -> String_map.bindings m) 1644 1644 ~enc:(fun l -> List.fold_left (fun m (k, v) -> 1645 1645 String_map.add k v m) String_map.empty l) 1646 1646 1647 1647 let jsont = 1648 - Jsont.Object.map ~kind:"Webfinger" 1648 + Json.Codec.Object.map ~kind:"Webfinger" 1649 1649 (fun subject aliases properties links -> 1650 1650 { subject; aliases; properties; links }) 1651 - |> Jsont.Object.mem "subject" Jsont.string ~enc:subject 1652 - |> Jsont.Object.opt_mem "aliases" (Jsont.list Jsont.string) ~enc:aliases 1653 - |> Jsont.Object.opt_mem "properties" properties_jsont ~enc:properties 1654 - |> Jsont.Object.opt_mem "links" (Jsont.list Jrd_link.jsont) ~enc:links 1655 - |> Jsont.Object.finish 1651 + |> Json.Codec.Object.member "subject" Json.Codec.string ~enc:subject 1652 + |> Json.Codec.Object.opt_member "aliases" (Json.Codec.list Json.Codec.string) ~enc:aliases 1653 + |> Json.Codec.Object.opt_member "properties" properties_jsont ~enc:properties 1654 + |> Json.Codec.Object.opt_member "links" (Json.Codec.list Jrd_link.jsont) ~enc:links 1655 + |> Json.Codec.Object.seal 1656 1656 end 1657 1657 1658 1658 (** {1 NodeInfo} *) ··· 1676 1676 val repository : t -> Uri.t option 1677 1677 val homepage : t -> Uri.t option 1678 1678 1679 - val jsont : t Jsont.t 1679 + val jsont : t Json.codec 1680 1680 end 1681 1681 1682 1682 (** Usage statistics. *) ··· 1697 1697 val local_posts : t -> int option 1698 1698 val local_comments : t -> int option 1699 1699 1700 - val jsont : t Jsont.t 1700 + val jsont : t Json.codec 1701 1701 end 1702 1702 1703 1703 type t ··· 1708 1708 protocols:string list -> 1709 1709 usage:Usage.t -> 1710 1710 open_registrations:bool -> 1711 - ?metadata:Jsont.json -> 1711 + ?metadata:Json.t -> 1712 1712 unit -> t 1713 1713 1714 1714 val version : t -> string ··· 1716 1716 val protocols : t -> string list 1717 1717 val usage : t -> Usage.t 1718 1718 val open_registrations : t -> bool 1719 - val metadata : t -> Jsont.json option 1719 + val metadata : t -> Json.t option 1720 1720 1721 - val jsont : t Jsont.t 1721 + val jsont : t Json.codec 1722 1722 end = struct 1723 1723 module Software = struct 1724 1724 type t = { ··· 1737 1737 let homepage t = t.homepage 1738 1738 1739 1739 let jsont = 1740 - Jsont.Object.map ~kind:"Software" 1740 + Json.Codec.Object.map ~kind:"Software" 1741 1741 (fun name version repository homepage -> 1742 1742 { name; version; repository; homepage }) 1743 - |> Jsont.Object.mem "name" Jsont.string ~enc:name 1744 - |> Jsont.Object.mem "version" Jsont.string ~enc:version 1745 - |> Jsont.Object.opt_mem "repository" uri_jsont ~enc:repository 1746 - |> Jsont.Object.opt_mem "homepage" uri_jsont ~enc:homepage 1747 - |> Jsont.Object.finish 1743 + |> Json.Codec.Object.member "name" Json.Codec.string ~enc:name 1744 + |> Json.Codec.Object.member "version" Json.Codec.string ~enc:version 1745 + |> Json.Codec.Object.opt_member "repository" uri_jsont ~enc:repository 1746 + |> Json.Codec.Object.opt_member "homepage" uri_jsont ~enc:homepage 1747 + |> Json.Codec.Object.seal 1748 1748 end 1749 1749 1750 1750 module Usage = struct ··· 1768 1768 let local_comments t = t.local_comments 1769 1769 1770 1770 let users_jsont = 1771 - Jsont.Object.map ~kind:"Users" 1771 + Json.Codec.Object.map ~kind:"Users" 1772 1772 (fun total active_half_year active_month -> 1773 1773 (total, active_half_year, active_month)) 1774 - |> Jsont.Object.opt_mem "total" Jsont.int 1774 + |> Json.Codec.Object.opt_member "total" Json.Codec.int 1775 1775 ~enc:(fun (t, _, _) -> t) 1776 - |> Jsont.Object.opt_mem "activeHalfyear" Jsont.int 1776 + |> Json.Codec.Object.opt_member "activeHalfyear" Json.Codec.int 1777 1777 ~enc:(fun (_, h, _) -> h) 1778 - |> Jsont.Object.opt_mem "activeMonth" Jsont.int 1778 + |> Json.Codec.Object.opt_member "activeMonth" Json.Codec.int 1779 1779 ~enc:(fun (_, _, m) -> m) 1780 - |> Jsont.Object.finish 1780 + |> Json.Codec.Object.seal 1781 1781 1782 1782 let jsont = 1783 - Jsont.Object.map ~kind:"Usage" 1783 + Json.Codec.Object.map ~kind:"Usage" 1784 1784 (fun (users_total, users_active_half_year, users_active_month) 1785 1785 local_posts local_comments -> 1786 1786 { users_total; users_active_half_year; users_active_month; 1787 1787 local_posts; local_comments }) 1788 - |> Jsont.Object.mem "users" users_jsont 1788 + |> Json.Codec.Object.member "users" users_jsont 1789 1789 ~dec_absent:(None, None, None) 1790 1790 ~enc:(fun t -> (t.users_total, t.users_active_half_year, 1791 1791 t.users_active_month)) 1792 - |> Jsont.Object.opt_mem "localPosts" Jsont.int ~enc:local_posts 1793 - |> Jsont.Object.opt_mem "localComments" Jsont.int ~enc:local_comments 1794 - |> Jsont.Object.finish 1792 + |> Json.Codec.Object.opt_member "localPosts" Json.Codec.int ~enc:local_posts 1793 + |> Json.Codec.Object.opt_member "localComments" Json.Codec.int ~enc:local_comments 1794 + |> Json.Codec.Object.seal 1795 1795 end 1796 1796 1797 1797 type t = { ··· 1800 1800 protocols : string list; 1801 1801 usage : Usage.t; 1802 1802 open_registrations : bool; 1803 - metadata : Jsont.json option; 1803 + metadata : Json.t option; 1804 1804 } 1805 1805 1806 1806 let make ~version ~software ~protocols ~usage ~open_registrations ··· 1815 1815 let metadata t = t.metadata 1816 1816 1817 1817 let jsont = 1818 - Jsont.Object.map ~kind:"Nodeinfo" 1818 + Json.Codec.Object.map ~kind:"Nodeinfo" 1819 1819 (fun version software protocols usage open_registrations metadata -> 1820 1820 { version; software; protocols; usage; open_registrations; metadata }) 1821 - |> Jsont.Object.mem "version" Jsont.string ~enc:version 1822 - |> Jsont.Object.mem "software" Software.jsont ~enc:software 1823 - |> Jsont.Object.mem "protocols" (Jsont.list Jsont.string) ~enc:protocols 1824 - |> Jsont.Object.mem "usage" Usage.jsont ~enc:usage 1825 - |> Jsont.Object.mem "openRegistrations" Jsont.bool ~enc:open_registrations 1826 - |> Jsont.Object.opt_mem "metadata" Jsont.json ~enc:metadata 1827 - |> Jsont.Object.finish 1821 + |> Json.Codec.Object.member "version" Json.Codec.string ~enc:version 1822 + |> Json.Codec.Object.member "software" Software.jsont ~enc:software 1823 + |> Json.Codec.Object.member "protocols" (Json.Codec.list Json.Codec.string) ~enc:protocols 1824 + |> Json.Codec.Object.member "usage" Usage.jsont ~enc:usage 1825 + |> Json.Codec.Object.member "openRegistrations" Json.Codec.bool ~enc:open_registrations 1826 + |> Json.Codec.Object.opt_member "metadata" Json.Codec.Value.t ~enc:metadata 1827 + |> Json.Codec.Object.seal 1828 1828 end
+36 -38
lib/proto/apubt_proto.mli
··· 1 - (** ActivityPub/ActivityStreams protocol types with jsont codecs. 1 + (** ActivityPub/ActivityStreams protocol types with nox-json codecs. 2 2 3 3 This module provides OCaml types and bidirectional JSON codecs for the 4 4 ActivityPub and ActivityStreams 2.0 specifications. It is the wire format ··· 9 9 {[ 10 10 (* Decode an actor from JSON *) 11 11 let json_str = {|{"@id": "...", "@type": "Person", ...}|} in 12 - match Jsont_bytesrw.decode_string Actor.jsont json_str with 12 + match Json.of_string Actor.jsont json_str with 13 13 | Ok actor -> Printf.printf "Actor: %s\n" (Option.value ~default:"" (Actor.name actor)) 14 - | Error e -> Printf.eprintf "Error: %a\n" Jsont.Error.pp e 14 + | Error e -> Printf.eprintf "Error: %a\n" Json.Error.pp e 15 15 16 16 (* Create and encode a Note *) 17 17 let note = Object.make ~type_:Object_type.Note 18 18 ~content:"Hello ActivityPub!" () in 19 - match Jsont_bytesrw.encode_string Object.jsont note with 20 - | Ok json_str -> print_endline json_str 21 - | Error e -> Printf.eprintf "Error: %a\n" Jsont.Error.pp e 19 + print_endline (Json.to_string Object.jsont note) 22 20 ]} 23 21 24 22 @see <https://www.w3.org/TR/activitypub/> ActivityPub specification ··· 37 35 val to_string : t -> string 38 36 (** [to_string t] returns the datetime as an ISO 8601 string. *) 39 37 40 - val jsont : t Jsont.t 38 + val jsont : t Json.codec 41 39 (** JSON type for datetimes. *) 42 40 end 43 41 44 - val uri_jsont : Uri.t Jsont.t 42 + val uri_jsont : Uri.t Json.codec 45 43 (** JSON codec for [Uri.t] values. *) 46 44 47 45 (** JSON-LD context. *) ··· 51 49 val default : t 52 50 (** The default ActivityStreams context. *) 53 51 54 - val jsont : t Jsont.t 52 + val jsont : t Json.codec 55 53 (** JSON type for contexts. *) 56 54 end 57 55 ··· 81 79 val width : t -> int option 82 80 val preview : t -> Uri.t option 83 81 84 - val jsont : t Jsont.t 82 + val jsont : t Json.codec 85 83 (** JSON type for Links. *) 86 84 end 87 85 ··· 93 91 94 92 val uri : Uri.t -> t 95 93 val link : Link.t -> t 96 - val jsont : t Jsont.t 94 + val jsont : t Json.codec 97 95 end 98 96 99 97 (** {1 Image} *) ··· 119 117 val width : t -> int option 120 118 val height : t -> int option 121 119 122 - val jsont : t Jsont.t 120 + val jsont : t Json.codec 123 121 end 124 122 125 123 (** Image reference - can be URI, Link, or full Image object. *) ··· 132 130 val uri : Uri.t -> t 133 131 val link : Link.t -> t 134 132 val image : Image.t -> t 135 - val jsont : t Jsont.t 133 + val jsont : t Json.codec 136 134 end 137 135 138 136 (** {1 Public Collection} *) ··· 152 150 val make : ?type_:string -> Uri.t -> t 153 151 val id : t -> Uri.t 154 152 val type_ : t -> string option 155 - val jsont : t Jsont.t 153 + val jsont : t Json.codec 156 154 end 157 155 158 156 (** {1 Endpoints} *) ··· 177 175 val sign_client_key : t -> Uri.t option 178 176 val shared_inbox : t -> Uri.t option 179 177 180 - val jsont : t Jsont.t 178 + val jsont : t Json.codec 181 179 end 182 180 183 181 (** {1 Public Key} *) ··· 196 194 val owner : t -> Uri.t 197 195 val public_key_pem : t -> string 198 196 199 - val jsont : t Jsont.t 197 + val jsont : t Json.codec 200 198 end 201 199 202 200 (** {1 Actor Types} *) ··· 212 210 213 211 val to_string : t -> string 214 212 val of_string : string -> t option 215 - val jsont : t Jsont.t 213 + val jsont : t Json.codec 216 214 end 217 215 218 216 (** {1 Actor} *) ··· 275 273 val featured : t -> Uri.t option 276 274 val featured_tags : t -> Uri.t option 277 275 278 - val jsont : t Jsont.t 276 + val jsont : t Json.codec 279 277 (** JSON type for Actors. *) 280 278 end 281 279 ··· 287 285 288 286 val uri : Uri.t -> t 289 287 val actor : Actor.t -> t 290 - val jsont : t Jsont.t 288 + val jsont : t Json.codec 291 289 end 292 290 293 291 (** {1 Object Types} *) ··· 311 309 312 310 val to_string : t -> string 313 311 val of_string : string -> t option 314 - val jsont : t Jsont.t 312 + val jsont : t Json.codec 315 313 end 316 314 317 315 (** {1 Object} *) ··· 392 390 val preview : t -> Link_or_uri.t option 393 391 (** [preview t] returns a preview of the object, typically a smaller version. *) 394 392 395 - val jsont : t Jsont.t 393 + val jsont : t Json.codec 396 394 (** JSON type for Objects. *) 397 395 end 398 396 ··· 404 402 405 403 val uri : Uri.t -> t 406 404 val obj : Object.t -> t 407 - val jsont : t Jsont.t 405 + val jsont : t Json.codec 408 406 end 409 407 410 408 (** {1 Activity Types} *) ··· 442 440 443 441 val to_string : t -> string 444 442 val of_string : string -> t option 445 - val jsont : t Jsont.t 443 + val jsont : t Json.codec 446 444 end 447 445 448 446 (** {1 Activity} *) ··· 505 503 val closed : t -> Datetime.t option 506 504 (** [closed t] returns when the poll was closed, for Question activities. *) 507 505 508 - val jsont : t Jsont.t 506 + val jsont : t Json.codec 509 507 (** JSON type for Activities. *) 510 508 end 511 509 ··· 517 515 518 516 val uri : Uri.t -> t 519 517 val activity : Activity.t -> t 520 - val jsont : t Jsont.t 518 + val jsont : t Json.codec 521 519 end 522 520 523 521 (** {1 Collection} *) ··· 548 546 val items : 'a t -> 'a list option 549 547 val ordered : 'a t -> bool 550 548 551 - val jsont : 'a Jsont.t -> 'a t Jsont.t 549 + val jsont : 'a Json.codec -> 'a t Json.codec 552 550 (** JSON type for Collections, parameterized by item type. *) 553 551 end 554 552 ··· 586 584 val items : 'a t -> 'a list option 587 585 val ordered : 'a t -> bool 588 586 589 - val jsont : 'a Jsont.t -> 'a t Jsont.t 587 + val jsont : 'a Json.codec -> 'a t Json.codec 590 588 (** JSON type for CollectionPages, parameterized by item type. *) 591 589 end 592 590 ··· 595 593 (** Activity collection. *) 596 594 module Activity_collection : sig 597 595 type t = Activity.t Collection.t 598 - val jsont : t Jsont.t 596 + val jsont : t Json.codec 599 597 end 600 598 601 599 (** Object collection. *) 602 600 module Object_collection : sig 603 601 type t = Object.t Collection.t 604 - val jsont : t Jsont.t 602 + val jsont : t Json.codec 605 603 end 606 604 607 605 (** Activity collection page. *) 608 606 module Activity_collection_page : sig 609 607 type t = Activity.t Collection_page.t 610 - val jsont : t Jsont.t 608 + val jsont : t Json.codec 611 609 end 612 610 613 611 (** Object collection page. *) 614 612 module Object_collection_page : sig 615 613 type t = Object.t Collection_page.t 616 - val jsont : t Jsont.t 614 + val jsont : t Json.codec 617 615 end 618 616 619 617 (** {1 Webfinger} *) ··· 637 635 val href : t -> Uri.t option 638 636 val template : t -> string option 639 637 640 - val jsont : t Jsont.t 638 + val jsont : t Json.codec 641 639 end 642 640 643 641 type t ··· 654 652 val properties : t -> (string * string) list option 655 653 val links : t -> Jrd_link.t list option 656 654 657 - val jsont : t Jsont.t 655 + val jsont : t Json.codec 658 656 end 659 657 660 658 (** {1 NodeInfo} *) ··· 678 676 val repository : t -> Uri.t option 679 677 val homepage : t -> Uri.t option 680 678 681 - val jsont : t Jsont.t 679 + val jsont : t Json.codec 682 680 end 683 681 684 682 (** Usage statistics. *) ··· 699 697 val local_posts : t -> int option 700 698 val local_comments : t -> int option 701 699 702 - val jsont : t Jsont.t 700 + val jsont : t Json.codec 703 701 end 704 702 705 703 type t ··· 710 708 protocols:string list -> 711 709 usage:Usage.t -> 712 710 open_registrations:bool -> 713 - ?metadata:Jsont.json -> 711 + ?metadata:Json.t -> 714 712 unit -> t 715 713 716 714 val version : t -> string ··· 718 716 val protocols : t -> string list 719 717 val usage : t -> Usage.t 720 718 val open_registrations : t -> bool 721 - val metadata : t -> Jsont.json option 719 + val metadata : t -> Json.t option 722 720 723 - val jsont : t Jsont.t 721 + val jsont : t Json.codec 724 722 end
+1 -1
lib/proto/dune
··· 1 1 (library 2 2 (name apubt_proto) 3 3 (public_name apubt.proto) 4 - (libraries jsont uri)) 4 + (libraries nox-json uri))