OCaml library for JSONfeed parsing and creation
1(*---------------------------------------------------------------------------
2 Copyright (c) 2024 Anil Madhavapeddy. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Attachments for JSON Feed items.
7
8 An attachment represents an external resource related to a feed item,
9 such as audio files for podcasts, video files, or other downloadable content.
10 Attachments with identical titles indicate alternate formats of the same resource.
11
12 @see <https://www.jsonfeed.org/version/1.1/> JSON Feed Specification *)
13
14
15(** The type representing an attachment. *)
16type t
17
18
19(** {1 Unknown Fields} *)
20
21module Unknown : sig
22 type t = (string * Jsont.json) list
23 (** Unknown/unrecognized JSON object members.
24 Useful for preserving fields from custom extensions or future spec versions. *)
25
26 val empty : t
27 (** [empty] is the empty list of unknown fields. *)
28
29 val is_empty : t -> bool
30 (** [is_empty u] returns [true] if there are no unknown fields. *)
31end
32
33
34(** {1 Jsont Type} *)
35
36val jsont : t Jsont.t
37(** Declarative JSON type for attachments.
38
39 Maps JSON objects with "url" (required), "mime_type" (required),
40 and optional "title", "size_in_bytes", "duration_in_seconds" fields. *)
41
42
43(** {1 Construction} *)
44
45val create :
46 url:string ->
47 mime_type:string ->
48 ?title:string ->
49 ?size_in_bytes:int64 ->
50 ?duration_in_seconds:int ->
51 unit ->
52 t
53(** [create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ()]
54 creates an attachment object.
55
56 @param url The location of the attachment (required)
57 @param mime_type The MIME type of the attachment, e.g. ["audio/mpeg"] (required)
58 @param title The name of the attachment; identical titles indicate alternate formats
59 of the same resource
60 @param size_in_bytes The size of the attachment file in bytes
61 @param duration_in_seconds The duration of the attachment in seconds (for audio/video)
62
63 {b Examples:}
64 {[
65 (* Simple attachment *)
66 let att = Attachment.create
67 ~url:"https://example.com/episode.mp3"
68 ~mime_type:"audio/mpeg" ()
69
70 (* Podcast episode with metadata *)
71 let att = Attachment.create
72 ~url:"https://example.com/episode.mp3"
73 ~mime_type:"audio/mpeg"
74 ~title:"Episode 42"
75 ~size_in_bytes:15_728_640L
76 ~duration_in_seconds:1800 ()
77 ]} *)
78
79val 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
90
91(** {1 Accessors} *)
92
93val url : t -> string
94(** [url t] returns the attachment's URL. *)
95
96val mime_type : t -> string
97(** [mime_type t] returns the attachment's MIME type. *)
98
99val title : t -> string option
100(** [title t] returns the attachment's title, if set. *)
101
102val size_in_bytes : t -> int64 option
103(** [size_in_bytes t] returns the attachment's size in bytes, if set. *)
104
105val duration_in_seconds : t -> int option
106(** [duration_in_seconds t] returns the attachment's duration, if set. *)
107
108val unknown : t -> Unknown.t
109(** [unknown t] returns unrecognized fields from the JSON. *)
110
111
112(** {1 Comparison} *)
113
114val equal : t -> t -> bool
115(** [equal a b] tests equality between two attachments. *)
116
117
118(** {1 Pretty Printing} *)
119
120val pp : Format.formatter -> t -> unit
121(** [pp ppf t] pretty prints an attachment to the formatter.
122
123 The output is human-readable and suitable for debugging.
124
125 {b Example output:}
126 {v episode.mp3 (audio/mpeg, 15.0 MB, 30m0s) v} *)