OCaml codecs for the Citation File Format (CFF)
at main 266 lines 7.3 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2026 The ocaml-cff programmers. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6(** Enumeration types for CFF using polymorphic variants. *) 7 8(** Functor to generate common enum operations. *) 9module type STRING_ENUM = sig 10 type t 11 12 val of_string : string -> t option 13 val to_string : t -> string 14 val type_name : string 15end 16 17module Make_enum (E : STRING_ENUM) = struct 18 include E 19 20 let equal (a : t) (b : t) = a = b 21 let compare = Stdlib.compare 22 let pp ppf t = Format.pp_print_string ppf (to_string t) 23 24 let jsont = 25 Jsont.string 26 |> Jsont.map 27 ~dec:(fun s -> 28 match of_string s with 29 | Some t -> t 30 | None -> Jsont.Error.msgf Jsont.Meta.none "Invalid %s: %s" type_name s) 31 ~enc:to_string 32 ;; 33end 34 35module Identifier_type = Make_enum (struct 36 type t = 37 [ `Doi 38 | `Url 39 | `Swh 40 | `Other 41 ] 42 43 let type_name = "identifier type" 44 45 let of_string = function 46 | "doi" -> Some `Doi 47 | "url" -> Some `Url 48 | "swh" -> Some `Swh 49 | "other" -> Some `Other 50 | _ -> None 51 ;; 52 53 let to_string = function 54 | `Doi -> "doi" 55 | `Url -> "url" 56 | `Swh -> "swh" 57 | `Other -> "other" 58 ;; 59 end) 60 61module Reference_type = Make_enum (struct 62 type t = 63 [ `Art 64 | `Article 65 | `Audiovisual 66 | `Bill 67 | `Blog 68 | `Book 69 | `Catalogue 70 | `Conference 71 | `Conference_paper 72 | `Data 73 | `Database 74 | `Dictionary 75 | `Edited_work 76 | `Encyclopedia 77 | `Film_broadcast 78 | `Generic 79 | `Government_document 80 | `Grant 81 | `Hearing 82 | `Historical_work 83 | `Legal_case 84 | `Legal_rule 85 | `Magazine_article 86 | `Manual 87 | `Map 88 | `Multimedia 89 | `Music 90 | `Newspaper_article 91 | `Pamphlet 92 | `Patent 93 | `Personal_communication 94 | `Proceedings 95 | `Report 96 | `Serial 97 | `Slides 98 | `Software 99 | `Software_code 100 | `Software_container 101 | `Software_executable 102 | `Software_virtual_machine 103 | `Sound_recording 104 | `Standard 105 | `Statute 106 | `Thesis 107 | `Unpublished 108 | `Video 109 | `Website 110 ] 111 112 let type_name = "reference type" 113 114 let of_string = function 115 | "art" -> Some `Art 116 | "article" -> Some `Article 117 | "audiovisual" -> Some `Audiovisual 118 | "bill" -> Some `Bill 119 | "blog" -> Some `Blog 120 | "book" -> Some `Book 121 | "catalogue" -> Some `Catalogue 122 | "conference" -> Some `Conference 123 | "conference-paper" -> Some `Conference_paper 124 | "data" -> Some `Data 125 | "database" -> Some `Database 126 | "dictionary" -> Some `Dictionary 127 | "edited-work" -> Some `Edited_work 128 | "encyclopedia" -> Some `Encyclopedia 129 | "film-broadcast" -> Some `Film_broadcast 130 | "generic" -> Some `Generic 131 | "government-document" -> Some `Government_document 132 | "grant" -> Some `Grant 133 | "hearing" -> Some `Hearing 134 | "historical-work" -> Some `Historical_work 135 | "legal-case" -> Some `Legal_case 136 | "legal-rule" -> Some `Legal_rule 137 | "magazine-article" -> Some `Magazine_article 138 | "manual" -> Some `Manual 139 | "map" -> Some `Map 140 | "multimedia" -> Some `Multimedia 141 | "music" -> Some `Music 142 | "newspaper-article" -> Some `Newspaper_article 143 | "pamphlet" -> Some `Pamphlet 144 | "patent" -> Some `Patent 145 | "personal-communication" -> Some `Personal_communication 146 | "proceedings" -> Some `Proceedings 147 | "report" -> Some `Report 148 | "serial" -> Some `Serial 149 | "slides" -> Some `Slides 150 | "software" -> Some `Software 151 | "software-code" -> Some `Software_code 152 | "software-container" -> Some `Software_container 153 | "software-executable" -> Some `Software_executable 154 | "software-virtual-machine" -> Some `Software_virtual_machine 155 | "sound-recording" -> Some `Sound_recording 156 | "standard" -> Some `Standard 157 | "statute" -> Some `Statute 158 | "thesis" -> Some `Thesis 159 | "unpublished" -> Some `Unpublished 160 | "video" -> Some `Video 161 | "website" -> Some `Website 162 | _ -> None 163 ;; 164 165 let to_string = function 166 | `Art -> "art" 167 | `Article -> "article" 168 | `Audiovisual -> "audiovisual" 169 | `Bill -> "bill" 170 | `Blog -> "blog" 171 | `Book -> "book" 172 | `Catalogue -> "catalogue" 173 | `Conference -> "conference" 174 | `Conference_paper -> "conference-paper" 175 | `Data -> "data" 176 | `Database -> "database" 177 | `Dictionary -> "dictionary" 178 | `Edited_work -> "edited-work" 179 | `Encyclopedia -> "encyclopedia" 180 | `Film_broadcast -> "film-broadcast" 181 | `Generic -> "generic" 182 | `Government_document -> "government-document" 183 | `Grant -> "grant" 184 | `Hearing -> "hearing" 185 | `Historical_work -> "historical-work" 186 | `Legal_case -> "legal-case" 187 | `Legal_rule -> "legal-rule" 188 | `Magazine_article -> "magazine-article" 189 | `Manual -> "manual" 190 | `Map -> "map" 191 | `Multimedia -> "multimedia" 192 | `Music -> "music" 193 | `Newspaper_article -> "newspaper-article" 194 | `Pamphlet -> "pamphlet" 195 | `Patent -> "patent" 196 | `Personal_communication -> "personal-communication" 197 | `Proceedings -> "proceedings" 198 | `Report -> "report" 199 | `Serial -> "serial" 200 | `Slides -> "slides" 201 | `Software -> "software" 202 | `Software_code -> "software-code" 203 | `Software_container -> "software-container" 204 | `Software_executable -> "software-executable" 205 | `Software_virtual_machine -> "software-virtual-machine" 206 | `Sound_recording -> "sound-recording" 207 | `Standard -> "standard" 208 | `Statute -> "statute" 209 | `Thesis -> "thesis" 210 | `Unpublished -> "unpublished" 211 | `Video -> "video" 212 | `Website -> "website" 213 ;; 214 end) 215 216module Status = Make_enum (struct 217 type t = 218 [ `Abstract 219 | `Advance_online 220 | `In_preparation 221 | `In_press 222 | `Preprint 223 | `Submitted 224 ] 225 226 let type_name = "status" 227 228 let of_string = function 229 | "abstract" -> Some `Abstract 230 | "advance-online" -> Some `Advance_online 231 | "in-preparation" -> Some `In_preparation 232 | "in-press" -> Some `In_press 233 | "preprint" -> Some `Preprint 234 | "submitted" -> Some `Submitted 235 | _ -> None 236 ;; 237 238 let to_string = function 239 | `Abstract -> "abstract" 240 | `Advance_online -> "advance-online" 241 | `In_preparation -> "in-preparation" 242 | `In_press -> "in-press" 243 | `Preprint -> "preprint" 244 | `Submitted -> "submitted" 245 ;; 246 end) 247 248module Cff_type = Make_enum (struct 249 type t = 250 [ `Software 251 | `Dataset 252 ] 253 254 let type_name = "CFF type" 255 256 let of_string = function 257 | "software" -> Some `Software 258 | "dataset" -> Some `Dataset 259 | _ -> None 260 ;; 261 262 let to_string = function 263 | `Software -> "software" 264 | `Dataset -> "dataset" 265 ;; 266 end)