OCaml library for JSONfeed parsing and creation
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2024 Anil Madhavapeddy. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6module Unknown = struct 7 type t = (string * Jsont.json) list 8 9 let empty = [] 10 let is_empty = function [] -> true | _ -> false 11end 12 13type t = { 14 name : string option; 15 url : string option; 16 avatar : string option; 17 unknown : Unknown.t; 18} 19 20let create ?name ?url ?avatar ?(unknown = Unknown.empty) () = 21 if name = None && url = None && avatar = None then 22 invalid_arg 23 "Author.create: at least one field (name, url, or avatar) must be \ 24 provided"; 25 { name; url; avatar; unknown } 26 27let name t = t.name 28let url t = t.url 29let avatar t = t.avatar 30let unknown t = t.unknown 31let is_valid t = t.name <> None || t.url <> None || t.avatar <> None 32let equal a b = a.name = b.name && a.url = b.url && a.avatar = b.avatar 33 34let pp ppf t = 35 match (t.name, t.url) with 36 | Some name, Some url -> Format.fprintf ppf "%s <%s>" name url 37 | Some name, None -> Format.fprintf ppf "%s" name 38 | None, Some url -> Format.fprintf ppf "<%s>" url 39 | None, None -> ( 40 match t.avatar with 41 | Some avatar -> Format.fprintf ppf "(avatar: %s)" avatar 42 | None -> Format.fprintf ppf "(empty author)") 43 44let jsont = 45 let kind = "Author" in 46 let doc = "An author object with at least one field set" in 47 (* Custom mems map for Unknown.t that strips metadata from names *) 48 let unknown_mems : 49 (Unknown.t, Jsont.json, Jsont.mem list) Jsont.Object.Mems.map = 50 let open Jsont.Object.Mems in 51 let dec_empty () = [] in 52 let dec_add _meta (name : string) value acc = 53 ((name, Jsont.Meta.none), value) :: acc 54 in 55 let dec_finish _meta mems = 56 List.rev_map (fun ((name, _meta), value) -> (name, value)) mems 57 in 58 let enc = 59 { 60 enc = 61 (fun (type acc) 62 (f : Jsont.Meta.t -> string -> Jsont.json -> acc -> acc) 63 unknown 64 (acc : acc) 65 -> 66 List.fold_left 67 (fun acc (name, value) -> f Jsont.Meta.none name value acc) 68 acc unknown); 69 } 70 in 71 map ~kind:"Unknown members" Jsont.json ~dec_empty ~dec_add ~dec_finish ~enc 72 in 73 (* Constructor that matches the jsont object map pattern *) 74 let create_obj name url avatar unknown = 75 create ?name ?url ?avatar ~unknown () 76 in 77 Jsont.Object.map ~kind ~doc create_obj 78 |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 79 |> Jsont.Object.opt_mem "url" Jsont.string ~enc:url 80 |> Jsont.Object.opt_mem "avatar" Jsont.string ~enc:avatar 81 |> Jsont.Object.keep_unknown unknown_mems ~enc:unknown 82 |> Jsont.Object.finish