OCaml codecs for the Citation File Format (CFF)
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)