OCaml library for JSONfeed parsing and creation

simplify

+40 -132
+4 -7
lib/attachment.ml
··· 19 19 unknown : Unknown.t; 20 20 } 21 21 22 - let make ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ?(unknown = Unknown.empty) () = 22 + let create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ?(unknown = Unknown.empty) () = 23 23 { url; mime_type; title; size_in_bytes; duration_in_seconds; unknown } 24 - 25 - let create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds () = 26 - make ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds () 27 24 28 25 let url t = t.url 29 26 let mime_type t = t.mime_type ··· 85 82 } in 86 83 map ~kind:"Unknown members" Jsont.json ~dec_empty ~dec_add ~dec_finish ~enc 87 84 in 88 - let make_obj url mime_type title size_in_bytes duration_in_seconds unknown = 89 - make ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ~unknown () 85 + let create_obj url mime_type title size_in_bytes duration_in_seconds unknown = 86 + create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ~unknown () 90 87 in 91 - Jsont.Object.map ~kind ~doc make_obj 88 + Jsont.Object.map ~kind ~doc create_obj 92 89 |> Jsont.Object.mem "url" Jsont.string ~enc:url 93 90 |> Jsont.Object.mem "mime_type" Jsont.string ~enc:mime_type 94 91 |> Jsont.Object.opt_mem "title" Jsont.string ~enc:title
+3 -12
lib/attachment.mli
··· 48 48 ?title:string -> 49 49 ?size_in_bytes:int64 -> 50 50 ?duration_in_seconds:int -> 51 + ?unknown:Unknown.t -> 51 52 unit -> 52 53 t 53 - (** [create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ()] 54 + (** [create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ?unknown ()] 54 55 creates an attachment object. 55 56 56 57 @param url The location of the attachment (required) ··· 59 60 of the same resource 60 61 @param size_in_bytes The size of the attachment file in bytes 61 62 @param duration_in_seconds The duration of the attachment in seconds (for audio/video) 63 + @param unknown Unknown/custom fields for extensions (default: empty) 62 64 63 65 {b Examples:} 64 66 {[ ··· 75 77 ~size_in_bytes:15_728_640L 76 78 ~duration_in_seconds:1800 () 77 79 ]} *) 78 - 79 - val make : 80 - url:string -> 81 - mime_type:string -> 82 - ?title:string -> 83 - ?size_in_bytes:int64 -> 84 - ?duration_in_seconds:int -> 85 - ?unknown:Unknown.t -> 86 - unit -> 87 - t 88 - (** [make] is like {!create} but allows setting unknown fields. *) 89 80 90 81 91 82 (** {1 Accessors} *)
+4 -7
lib/author.ml
··· 17 17 unknown : Unknown.t; 18 18 } 19 19 20 - let make ?name ?url ?avatar ?(unknown = Unknown.empty) () = 21 - { name; url; avatar; unknown } 22 - 23 - let create ?name ?url ?avatar () = 20 + let create ?name ?url ?avatar ?(unknown = Unknown.empty) () = 24 21 if name = None && url = None && avatar = None then 25 22 invalid_arg "Author.create: at least one field (name, url, or avatar) must be provided"; 26 - make ?name ?url ?avatar () 23 + { name; url; avatar; unknown } 27 24 28 25 let name t = t.name 29 26 let url t = t.url ··· 70 67 map ~kind:"Unknown members" Jsont.json ~dec_empty ~dec_add ~dec_finish ~enc 71 68 in 72 69 (* Constructor that matches the jsont object map pattern *) 73 - let make_obj name url avatar unknown = make ?name ?url ?avatar ~unknown () in 74 - Jsont.Object.map ~kind ~doc make_obj 70 + let create_obj name url avatar unknown = create ?name ?url ?avatar ~unknown () in 71 + Jsont.Object.map ~kind ~doc create_obj 75 72 |> Jsont.Object.opt_mem "name" Jsont.string ~enc:name 76 73 |> Jsont.Object.opt_mem "url" Jsont.string ~enc:url 77 74 |> Jsont.Object.opt_mem "avatar" Jsont.string ~enc:avatar
+5 -8
lib/author.mli
··· 42 42 43 43 (** {1 Construction} *) 44 44 45 - val create : ?name:string -> ?url:string -> ?avatar:string -> unit -> t 46 - (** [create ?name ?url ?avatar ()] creates an author. 45 + val create : 46 + ?name:string -> ?url:string -> ?avatar:string -> 47 + ?unknown:Unknown.t -> unit -> t 48 + (** [create ?name ?url ?avatar ?unknown ()] creates an author. 47 49 48 50 At least one of the optional parameters must be provided, otherwise 49 51 the function will raise [Invalid_argument]. ··· 51 53 @param name The author's name 52 54 @param url URL of the author's website or profile 53 55 @param avatar URL of the author's avatar image (should be square, 512x512 or larger) 56 + @param unknown Unknown/custom fields for extensions (default: empty) 54 57 55 58 {b Examples:} 56 59 {[ ··· 61 64 ~url:"https://janedoe.com" 62 65 ~avatar:"https://janedoe.com/avatar.png" () 63 66 ]} *) 64 - 65 - val make : 66 - ?name:string -> ?url:string -> ?avatar:string -> 67 - ?unknown:Unknown.t -> unit -> t 68 - (** [make] is like {!create} but allows setting unknown fields. 69 - Useful when round-tripping JSON with custom extensions. *) 70 67 71 68 72 69 (** {1 Accessors} *)
+3 -6
lib/hub.ml
··· 16 16 unknown : Unknown.t; 17 17 } 18 18 19 - let make ~type_ ~url ?(unknown = Unknown.empty) () = 19 + let create ~type_ ~url ?(unknown = Unknown.empty) () = 20 20 { type_; url; unknown } 21 - 22 - let create ~type_ ~url () = 23 - make ~type_ ~url () 24 21 25 22 let type_ t = t.type_ 26 23 let url t = t.url ··· 51 48 } in 52 49 map ~kind:"Unknown members" Jsont.json ~dec_empty ~dec_add ~dec_finish ~enc 53 50 in 54 - let make_obj type_ url unknown = make ~type_ ~url ~unknown () in 55 - Jsont.Object.map ~kind ~doc make_obj 51 + let create_obj type_ url unknown = create ~type_ ~url ~unknown () in 52 + Jsont.Object.map ~kind ~doc create_obj 56 53 |> Jsont.Object.mem "type" Jsont.string ~enc:type_ 57 54 |> Jsont.Object.mem "url" Jsont.string ~enc:url 58 55 |> Jsont.Object.keep_unknown unknown_mems ~enc:unknown
+5 -7
lib/hub.mli
··· 41 41 42 42 (** {1 Construction} *) 43 43 44 - val create : type_:string -> url:string -> unit -> t 45 - (** [create ~type_ ~url ()] creates a hub object. 44 + val create : 45 + type_:string -> url:string -> 46 + ?unknown:Unknown.t -> unit -> t 47 + (** [create ~type_ ~url ?unknown ()] creates a hub object. 46 48 47 49 @param type_ The type of hub protocol (e.g., ["rssCloud"], ["WebSub"]) 48 50 @param url The URL endpoint for the hub 51 + @param unknown Unknown/custom fields for extensions (default: empty) 49 52 50 53 {b Example:} 51 54 {[ ··· 53 56 ~type_:"WebSub" 54 57 ~url:"https://pubsubhubbub.appspot.com/" () 55 58 ]} *) 56 - 57 - val make : 58 - type_:string -> url:string -> 59 - ?unknown:Unknown.t -> unit -> t 60 - (** [make] is like {!create} but allows setting unknown fields. *) 61 59 62 60 63 61 (** {1 Accessors} *)
+1 -6
lib/item.ml
··· 35 35 unknown : Unknown.t; 36 36 } 37 37 38 - let make ~id ~content ?url ?external_url ?title ?summary ?image ?banner_image 38 + let create ~id ~content ?url ?external_url ?title ?summary ?image ?banner_image 39 39 ?date_published ?date_modified ?authors ?tags ?language ?attachments ?references 40 40 ?(unknown = Unknown.empty) () = 41 41 { ··· 43 43 date_published; date_modified; authors; tags; language; attachments; references; 44 44 unknown; 45 45 } 46 - 47 - let create ~id ~content ?url ?external_url ?title ?summary ?image ?banner_image 48 - ?date_published ?date_modified ?authors ?tags ?language ?attachments ?references () = 49 - make ~id ~content ?url ?external_url ?title ?summary ?image ?banner_image 50 - ?date_published ?date_modified ?authors ?tags ?language ?attachments ?references () 51 46 52 47 let id t = t.id 53 48 let content t = t.content
-19
lib/item.mli
··· 71 71 ?language:string -> 72 72 ?attachments:Attachment.t list -> 73 73 ?references:Reference.t list -> 74 - unit -> 75 - t 76 - 77 - val make : 78 - id:string -> 79 - content:content -> 80 - ?url:string -> 81 - ?external_url:string -> 82 - ?title:string -> 83 - ?summary:string -> 84 - ?image:string -> 85 - ?banner_image:string -> 86 - ?date_published:Ptime.t -> 87 - ?date_modified:Ptime.t -> 88 - ?authors:Author.t list -> 89 - ?tags:string list -> 90 - ?language:string -> 91 - ?attachments:Attachment.t list -> 92 - ?references:Reference.t list -> 93 74 ?unknown:Unknown.t -> 94 75 unit -> 95 76 t
+1 -6
lib/jsonfeed.ml
··· 36 36 unknown : Unknown.t; 37 37 } 38 38 39 - let make ~title ?home_page_url ?feed_url ?description ?user_comment 39 + let create ~title ?home_page_url ?feed_url ?description ?user_comment 40 40 ?next_url ?icon ?favicon ?authors ?language ?expired ?hubs ~items 41 41 ?(unknown = Unknown.empty) () = 42 42 { ··· 56 56 items; 57 57 unknown; 58 58 } 59 - 60 - let create ~title ?home_page_url ?feed_url ?description ?user_comment 61 - ?next_url ?icon ?favicon ?authors ?language ?expired ?hubs ~items () = 62 - make ~title ?home_page_url ?feed_url ?description ?user_comment 63 - ?next_url ?icon ?favicon ?authors ?language ?expired ?hubs ~items () 64 59 65 60 let version t = t.version 66 61 let title t = t.title
+8 -38
lib/jsonfeed.mli
··· 12 12 type t 13 13 14 14 15 - (** {1 Unknown Fields} *) 15 + (** {1 Jsont Type} *) 16 + 17 + val jsont : t Jsont.t 18 + (** Declarative JSON type for JSON feeds. 19 + 20 + Maps the complete JSON Feed 1.1 specification including all required 21 + and optional fields. *) 16 22 17 23 module Unknown : sig 18 24 type t = (string * Jsont.json) list ··· 26 32 (** [is_empty u] returns [true] if there are no unknown fields. *) 27 33 end 28 34 29 - 30 - (** {1 Jsont Type} *) 31 - 32 - val jsont : t Jsont.t 33 - (** Declarative JSON type for JSON feeds. 34 - 35 - Maps the complete JSON Feed 1.1 specification including all required 36 - and optional fields. *) 37 - 38 - 39 - (** {1 Construction} *) 40 - 41 35 val create : 42 36 title:string -> 43 37 ?home_page_url:string -> ··· 52 46 ?expired:bool -> 53 47 ?hubs:Hub.t list -> 54 48 items:Item.t list -> 55 - unit -> 56 - t 57 - 58 - val make : 59 - title:string -> 60 - ?home_page_url:string -> 61 - ?feed_url:string -> 62 - ?description:string -> 63 - ?user_comment:string -> 64 - ?next_url:string -> 65 - ?icon:string -> 66 - ?favicon:string -> 67 - ?authors:Author.t list -> 68 - ?language:string -> 69 - ?expired:bool -> 70 - ?hubs:Hub.t list -> 71 - items:Item.t list -> 72 49 ?unknown:Unknown.t -> 73 50 unit -> 74 51 t 75 - 76 - 77 - (** {1 Accessors} *) 78 52 79 53 val version : t -> string 80 54 val title : t -> string ··· 92 66 val items : t -> Item.t list 93 67 val unknown : t -> Unknown.t 94 68 95 - 96 - (** {1 Encoding and Decoding with Bytesrw} *) 69 + (** {1 Encoding and Decoding} *) 97 70 98 71 val decode : 99 72 ?layout:bool -> ?locs:bool -> ?file:string -> ··· 124 97 (** [encode_string feed] encodes [feed] to a string. *) 125 98 126 99 127 - (** {1 Convenience Functions} *) 128 - 129 100 val of_string : string -> (t, Jsont.Error.t) result 130 101 (** Alias for [decode_string] with default options. *) 131 102 ··· 151 122 152 123 val pp : Format.formatter -> t -> unit 153 124 val pp_summary : Format.formatter -> t -> unit 154 - 155 125 156 126 (** {1 Submodules} *) 157 127
+3 -6
lib/reference.ml
··· 17 17 unknown : Unknown.t; 18 18 } 19 19 20 - let make ~url ?doi ?cito ?(unknown = Unknown.empty) () = 20 + let create ~url ?doi ?cito ?(unknown = Unknown.empty) () = 21 21 { url; doi; cito; unknown } 22 - 23 - let create ~url ?doi ?cito () = 24 - make ~url ?doi ?cito () 25 22 26 23 let url t = t.url 27 24 let doi t = t.doi ··· 57 54 } in 58 55 map ~kind:"Unknown members" Jsont.json ~dec_empty ~dec_add ~dec_finish ~enc 59 56 in 60 - let make_obj url doi cito unknown = make ~url ?doi ?cito ~unknown () in 61 - Jsont.Object.map ~kind ~doc make_obj 57 + let create_obj url doi cito unknown = create ~url ?doi ?cito ~unknown () in 58 + Jsont.Object.map ~kind ~doc create_obj 62 59 |> Jsont.Object.mem "url" Jsont.string ~enc:url 63 60 |> Jsont.Object.opt_mem "doi" Jsont.string ~enc:doi 64 61 |> Jsont.Object.opt_mem "cito" (Jsont.list Cito.jsont) ~enc:cito
+3 -10
lib/reference.mli
··· 45 45 url:string -> 46 46 ?doi:string -> 47 47 ?cito:Cito.t list -> 48 + ?unknown:Unknown.t -> 48 49 unit -> 49 50 t 50 - (** [create ~url ?doi ?cito ()] creates a reference. 51 + (** [create ~url ?doi ?cito ?unknown ()] creates a reference. 51 52 52 53 @param url Unique URL for the reference (required). 53 54 A URL based on a persistent unique identifier (like DOI) is recommended. 54 55 @param doi Digital Object Identifier for the reference 55 56 @param cito Citation Typing Ontology intent annotations 57 + @param unknown Unknown/custom fields for extensions (default: empty) 56 58 57 59 {b Examples:} 58 60 {[ ··· 74 76 ~cito:[`CitesAsRecommendedReading; `UsesMethodIn] 75 77 () 76 78 ]} *) 77 - 78 - val make : 79 - url:string -> 80 - ?doi:string -> 81 - ?cito:Cito.t list -> 82 - ?unknown:Unknown.t -> 83 - unit -> 84 - t 85 - (** [make] is like {!create} but allows setting unknown fields. *) 86 79 87 80 88 81 (** {1 Accessors} *)