OCaml codecs for the Citation File Format (CFF)
at main 101 lines 3.2 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2026 The ocaml-cff programmers. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Address and contact information for CFF. *) 7 8(** Physical address information. *) 9module Address = struct 10 type t = 11 { address : string option 12 ; city : string option 13 ; region : string option 14 ; post_code : string option 15 ; country : string option (* ISO 3166-1 alpha-2 *) 16 } 17 18 let empty = 19 { address = None; city = None; region = None; post_code = None; country = None } 20 ;; 21 22 let make ?address ?city ?region ?post_code ?country () = 23 { address; city; region; post_code; country } 24 ;; 25 26 let of_options ~address ~city ~region ~post_code ~country = 27 { address; city; region; post_code; country } 28 ;; 29 30 let address t = t.address 31 let city t = t.city 32 let region t = t.region 33 let post_code t = t.post_code 34 let country t = t.country 35 36 let is_empty t = 37 t.address = None 38 && t.city = None 39 && t.region = None 40 && t.post_code = None 41 && t.country = None 42 ;; 43 44 let pp ppf t = 45 let parts = 46 List.filter_map Fun.id [ t.address; t.city; t.region; t.post_code; t.country ] 47 in 48 Format.pp_print_string ppf (String.concat ", " parts) 49 ;; 50 51 let jsont_fields ~get obj = 52 obj 53 |> Jsont.Object.opt_mem "address" Jsont.string ~enc:(fun x -> (get x).address) 54 |> Jsont.Object.opt_mem "city" Jsont.string ~enc:(fun x -> (get x).city) 55 |> Jsont.Object.opt_mem "region" Jsont.string ~enc:(fun x -> (get x).region) 56 |> Jsont.Object.opt_mem "post-code" Jsont.string ~enc:(fun x -> (get x).post_code) 57 |> Jsont.Object.opt_mem "country" Jsont.string ~enc:(fun x -> (get x).country) 58 ;; 59end 60 61(** Contact information. *) 62module Contact = struct 63 type t = 64 { email : string option 65 ; tel : string option 66 ; fax : string option 67 ; website : string option 68 ; orcid : string option 69 } 70 71 let empty = { email = None; tel = None; fax = None; website = None; orcid = None } 72 let make ?email ?tel ?fax ?website ?orcid () = { email; tel; fax; website; orcid } 73 let of_options ~email ~tel ~fax ~website ~orcid = { email; tel; fax; website; orcid } 74 let email t = t.email 75 let tel t = t.tel 76 let fax t = t.fax 77 let website t = t.website 78 let orcid t = t.orcid 79 80 let is_empty t = 81 t.email = None && t.tel = None && t.fax = None && t.website = None && t.orcid = None 82 ;; 83 84 let pp ppf t = 85 let parts = 86 List.filter_map 87 (fun (k, v) -> Option.map (fun v -> k ^ ": " ^ v) v) 88 [ "email", t.email; "tel", t.tel; "website", t.website; "orcid", t.orcid ] 89 in 90 Format.pp_print_string ppf (String.concat ", " parts) 91 ;; 92 93 let jsont_fields ~get obj = 94 obj 95 |> Jsont.Object.opt_mem "email" Jsont.string ~enc:(fun x -> (get x).email) 96 |> Jsont.Object.opt_mem "tel" Jsont.string ~enc:(fun x -> (get x).tel) 97 |> Jsont.Object.opt_mem "fax" Jsont.string ~enc:(fun x -> (get x).fax) 98 |> Jsont.Object.opt_mem "website" Jsont.string ~enc:(fun x -> (get x).website) 99 |> Jsont.Object.opt_mem "orcid" Jsont.string ~enc:(fun x -> (get x).orcid) 100 ;; 101end