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 = Jsont.json
8
9 let empty = Jsont.Object ([], Jsont.Meta.none)
10 let is_empty = function Jsont.Object ([], _) -> true | _ -> false
11end
12
13type t = {
14 url : string;
15 mime_type : string;
16 title : string option;
17 size_in_bytes : int64 option;
18 duration_in_seconds : int option;
19 unknown : Unknown.t;
20}
21
22let create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds
23 ?(unknown = Unknown.empty) () =
24 { url; mime_type; title; size_in_bytes; duration_in_seconds; unknown }
25
26let url t = t.url
27let mime_type t = t.mime_type
28let title t = t.title
29let size_in_bytes t = t.size_in_bytes
30let duration_in_seconds t = t.duration_in_seconds
31let unknown t = t.unknown
32
33let equal a b =
34 a.url = b.url && a.mime_type = b.mime_type && a.title = b.title
35 && a.size_in_bytes = b.size_in_bytes
36 && a.duration_in_seconds = b.duration_in_seconds
37
38let pp ppf t =
39 (* Extract filename from URL *)
40 let filename =
41 try
42 let parts = String.split_on_char '/' t.url in
43 List.nth parts (List.length parts - 1)
44 with _ -> t.url
45 in
46
47 Format.fprintf ppf "%s (%s" filename t.mime_type;
48
49 (match t.size_in_bytes with
50 | Some size ->
51 let mb = Int64.to_float size /. (1024. *. 1024.) in
52 Format.fprintf ppf ", %.1f MB" mb
53 | None -> ());
54
55 (match t.duration_in_seconds with
56 | Some duration ->
57 let mins = duration / 60 in
58 let secs = duration mod 60 in
59 Format.fprintf ppf ", %dm%ds" mins secs
60 | None -> ());
61
62 Format.fprintf ppf ")"
63
64let jsont =
65 let kind = "Attachment" in
66 let doc = "An attachment object" in
67 let create_obj url mime_type title size_in_bytes duration_in_seconds unknown =
68 create ~url ~mime_type ?title ?size_in_bytes ?duration_in_seconds ~unknown
69 ()
70 in
71 Jsont.Object.map ~kind ~doc create_obj
72 |> Jsont.Object.mem "url" Jsont.string ~enc:url
73 |> Jsont.Object.mem "mime_type" Jsont.string ~enc:mime_type
74 |> Jsont.Object.opt_mem "title" Jsont.string ~enc:title
75 |> Jsont.Object.opt_mem "size_in_bytes" Jsont.int64 ~enc:size_in_bytes
76 |> Jsont.Object.opt_mem "duration_in_seconds" Jsont.int
77 ~enc:duration_in_seconds
78 |> Jsont.Object.keep_unknown Jsont.json_mems ~enc:unknown
79 |> Jsont.Object.finish