citeworks_cff/
references.rs

1//! Types and utilities for references to this or other works.
2
3use serde::{Deserialize, Serialize};
4use url::Url;
5
6use crate::{
7	identifiers::Identifier,
8	names::{EntityName, Name},
9	Date, License,
10};
11
12/// A reference for a work.
13#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
14#[serde(rename_all = "kebab-case")]
15pub struct Reference {
16	/// The type of the referenced work.
17	///
18	/// This is required.
19	#[serde(rename = "type")]
20	pub work_type: RefType,
21
22	/// The authors of the work.
23	///
24	/// This is required and must contain at least one author.
25	pub authors: Vec<Name>,
26
27	/// The abbreviation of a work.
28	#[serde(default, skip_serializing_if = "Option::is_none")]
29	pub abbreviation: Option<String>,
30
31	/// The abstract of the work.
32	///
33	/// - If the work is a journal paper or other academic work,
34	///   The abstract of the work.
35	///
36	/// - If the work is a film broadcast or similar,
37	///   The synopsis of the work.
38	#[serde(default, skip_serializing_if = "Option::is_none", rename = "abstract")]
39	pub abstract_text: Option<String>,
40
41	/// The DOI of a collection containing the work.
42	#[serde(default, skip_serializing_if = "Option::is_none")]
43	pub collection_doi: Option<String>,
44
45	/// The title of a collection or proceedings.
46	#[serde(default, skip_serializing_if = "Option::is_none")]
47	pub collection_title: Option<String>,
48
49	/// The type of a collection.
50	///
51	/// By convention this should be in lowercase.
52	#[serde(default, skip_serializing_if = "Option::is_none")]
53	pub collection_type: Option<String>,
54
55	/// The commit hash or revision number of the work, if it is software.
56	///
57	/// By convention:
58	/// - if this is a Git hash, it should be bare lowercase hex, e.g.
59	///   `1ff847d81f29c45a3a1a5ce73d38e45c2f319bba`;
60	/// - if this is a decimal revision or build number, it should be preceded
61	///   by a label, e.g. `Revision: 8612`.
62	#[serde(default, skip_serializing_if = "Option::is_none")]
63	pub commit: Option<String>,
64
65	/// The conference where the work was presented.
66	#[serde(default, skip_serializing_if = "Option::is_none")]
67	pub conference: Option<EntityName>,
68
69	/// The contact person, group, company, etc. for a work.
70	#[serde(default, skip_serializing_if = "Vec::is_empty")]
71	pub contact: Vec<Name>,
72
73	/// The copyright information pertaining to the work.
74	#[serde(default, skip_serializing_if = "Option::is_none")]
75	pub copyright: Option<String>,
76
77	/// The data type of a data set.
78	#[serde(default, skip_serializing_if = "Option::is_none")]
79	pub data_type: Option<String>,
80
81	/// The provider of the database where a work was accessed/is stored.
82	#[serde(default, skip_serializing_if = "Option::is_none")]
83	pub database_provider: Option<EntityName>,
84
85	/// The name of the database where a work was accessed/is stored.
86	#[serde(default, skip_serializing_if = "Option::is_none")]
87	pub database: Option<String>,
88
89	/// The date the work was accessed.
90	#[serde(default, skip_serializing_if = "Option::is_none")]
91	pub date_accessed: Option<Date>,
92
93	/// The date the work has been downloaded.
94	#[serde(default, skip_serializing_if = "Option::is_none")]
95	pub date_downloaded: Option<Date>,
96
97	/// The date the work has been published.
98	#[serde(default, skip_serializing_if = "Option::is_none")]
99	pub date_published: Option<Date>,
100
101	/// The date the work has been released.
102	#[serde(default, skip_serializing_if = "Option::is_none")]
103	pub date_released: Option<Date>,
104
105	/// The department where a work has been produced.
106	#[serde(default, skip_serializing_if = "Option::is_none")]
107	pub department: Option<String>,
108
109	/// The DOI of the work.
110	#[serde(default, skip_serializing_if = "Option::is_none")]
111	pub doi: Option<String>,
112
113	/// The edition of the work.
114	#[serde(default, skip_serializing_if = "Option::is_none")]
115	pub edition: Option<String>,
116
117	/// The editor(s) of a work.
118	#[serde(default, skip_serializing_if = "Vec::is_empty")]
119	pub editors: Vec<Name>,
120
121	/// The editor(s) of a series in which the work has been published.
122	#[serde(default, skip_serializing_if = "Vec::is_empty")]
123	pub editors_series: Vec<Name>,
124
125	/// The start page of the work.
126	#[serde(default, skip_serializing_if = "Option::is_none")]
127	pub start: Option<u64>,
128
129	/// The end page of the work.
130	#[serde(default, skip_serializing_if = "Option::is_none")]
131	pub end: Option<u64>,
132
133	/// An entry in the collection that constitutes the work.
134	#[serde(default, skip_serializing_if = "Option::is_none")]
135	pub entry: Option<String>,
136
137	/// The name of the electronic file containing the work.
138	#[serde(default, skip_serializing_if = "Option::is_none")]
139	pub filename: Option<String>,
140
141	/// The format in which a work is represented.
142	#[serde(default, skip_serializing_if = "Option::is_none")]
143	pub format: Option<String>,
144
145	/// The identifier(s) of the work.
146	#[serde(default, skip_serializing_if = "Vec::is_empty")]
147	pub identifiers: Vec<Identifier>,
148
149	/// The institution where a work has been produced or published.
150	#[serde(default, skip_serializing_if = "Option::is_none")]
151	pub institution: Option<EntityName>,
152
153	/// The [ISBN] of the work.
154	///
155	/// The value is not validated.
156	///
157	/// [ISBN]: https://en.wikipedia.org/wiki/International_Standard_Book_Number
158	#[serde(default, skip_serializing_if = "Option::is_none")]
159	pub isbn: Option<String>,
160
161	/// The [ISSN] of the work.
162	///
163	/// The value is not validated.
164	///
165	/// [ISSN]: https://en.wikipedia.org/wiki/International_Standard_Serial_Number
166	#[serde(default, skip_serializing_if = "Option::is_none")]
167	pub issn: Option<String>,
168
169	/// The issue of a periodical in which a work appeared.
170	#[serde(default, skip_serializing_if = "Option::is_none")]
171	pub issue: Option<String>,
172
173	/// The publication date of the issue of a periodical in which a work appeared.
174	///
175	/// Note this is a freeform string.
176	#[serde(default, skip_serializing_if = "Option::is_none")]
177	pub issue_date: Option<String>,
178
179	/// The name of the issue of a periodical in which the work appeared.
180	#[serde(default, skip_serializing_if = "Option::is_none")]
181	pub issue_title: Option<String>,
182
183	/// The name of the journal/magazine/newspaper/periodical where the work was published.
184	#[serde(default, skip_serializing_if = "Option::is_none")]
185	pub journal: Option<String>,
186
187	/// Keywords pertaining to the work.
188	#[serde(default, skip_serializing_if = "Vec::is_empty")]
189	pub keywords: Vec<String>,
190
191	/// The language identifier(s) of the work.
192	///
193	/// These should be ISO639 strings in lowercase alpha-2 or alpha-3, but this
194	/// library does not validate this.
195	#[serde(default, skip_serializing_if = "Vec::is_empty")]
196	pub languages: Vec<String>,
197
198	/// [SPDX][spdx] license expression(s).
199	#[serde(default, skip_serializing_if = "Option::is_none")]
200	pub license: Option<License>,
201
202	/// The URL of the license text under which the work is licensed.
203	///
204	/// This should only be used for non-standard licenses not included in the
205	/// SPDX License List.
206	#[serde(default, skip_serializing_if = "Option::is_none")]
207	pub license_url: Option<Url>,
208
209	/// The line of code in the file where the work ends.
210	#[serde(default, skip_serializing_if = "Option::is_none")]
211	pub loc_end: Option<u64>,
212
213	/// The line of code in the file where the work starts.
214	#[serde(default, skip_serializing_if = "Option::is_none")]
215	pub loc_start: Option<u64>,
216
217	/// The location of the work.
218	#[serde(default, skip_serializing_if = "Option::is_none")]
219	pub location: Option<EntityName>,
220
221	/// The medium of the work.
222	#[serde(default, skip_serializing_if = "Option::is_none")]
223	pub medium: Option<String>,
224
225	/// The month in which a work has been published.
226	///
227	/// Should be an integer in the range 1-12. Note this is not validated.
228	#[serde(default, skip_serializing_if = "Option::is_none")]
229	pub month: Option<u8>,
230
231	/// The [NIHMSID] of a work.
232	///
233	/// [NIHMSID]: https://web.archive.org/web/20210802210057/https://www.ncbi.nlm.nih.gov/pmc/about/public-access-info/
234	#[serde(default, skip_serializing_if = "Option::is_none")]
235	pub nihmsid: Option<String>,
236
237	/// Notes pertaining to the work.
238	///
239	/// Note that this key should contain notes that may be picked up by some
240	/// downstream tooling (e.g., reference managers), but not others
241	/// (e.g., a software index).
242	#[serde(default, skip_serializing_if = "Option::is_none")]
243	pub notes: Option<String>,
244
245	/// The (library) [accession number] for a work.
246	///
247	/// [accession number]: https://en.wikipedia.org/wiki/Accession_number
248	#[serde(default, skip_serializing_if = "Option::is_none")]
249	pub number: Option<String>,
250
251	/// The number of volumes making up the collection in which the work has
252	/// been published.
253	#[serde(default, skip_serializing_if = "Option::is_none")]
254	pub number_volumes: Option<u64>,
255
256	/// The number of pages of the work.
257	#[serde(default, skip_serializing_if = "Option::is_none")]
258	pub pages: Option<u64>,
259
260	/// The states for which a patent is granted.
261	#[serde(default, skip_serializing_if = "Vec::is_empty")]
262	pub patent_states: Vec<String>,
263
264	/// The [PMCID] of a work.
265	///
266	/// The value is not validated.
267	///
268	/// [PMCID]: https://web.archive.org/web/20210802210057/https://www.ncbi.nlm.nih.gov/pmc/about/public-access-info/
269	#[serde(default, skip_serializing_if = "Option::is_none")]
270	pub pmcid: Option<String>,
271
272	/// The publisher who has published the work.
273	#[serde(default, skip_serializing_if = "Option::is_none")]
274	pub publisher: Option<EntityName>,
275
276	/// The recipient(s) of a personal communication.
277	#[serde(default, skip_serializing_if = "Vec::is_empty")]
278	pub recipients: Vec<Name>,
279
280	/// The URL of the work in a repository/archive.
281	///
282	/// This is to be used when the repository is neither a source code
283	/// repository nor a build artifact repository. For source code, use the
284	/// `repository_code` field; for binary releases or other built forms, use
285	/// the `repository_artifact` field.
286	#[serde(default, skip_serializing_if = "Option::is_none")]
287	pub repository: Option<Url>,
288
289	/// The URL of the work in a build artifact/binary repository.
290	#[serde(default, skip_serializing_if = "Option::is_none")]
291	pub repository_artifact: Option<Url>,
292
293	/// The URL of the work in a source code repository.
294	#[serde(default, skip_serializing_if = "Option::is_none")]
295	pub repository_code: Option<Url>,
296
297	/// The scope of the reference, e.g., the section of the work it adheres to.
298	#[serde(default, skip_serializing_if = "Option::is_none")]
299	pub scope: Option<String>,
300
301	/// The section of a work that is referenced.
302	#[serde(default, skip_serializing_if = "Option::is_none")]
303	pub section: Option<String>,
304
305	/// The sender(s) of a personal communication.
306	#[serde(default, skip_serializing_if = "Vec::is_empty")]
307	pub senders: Vec<Name>,
308
309	/// The publication status of the work.
310	#[serde(default, skip_serializing_if = "Option::is_none")]
311	pub status: Option<PublicationStatus>,
312
313	/// The term being referenced if the work is a dictionary or encyclopedia.
314	#[serde(default, skip_serializing_if = "Option::is_none")]
315	pub term: Option<String>,
316
317	/// The type of the thesis that is the work.
318	#[serde(default, skip_serializing_if = "Option::is_none")]
319	pub thesis_type: Option<String>,
320
321	/// The title of the work.
322	#[serde(default, skip_serializing_if = "Option::is_none")]
323	pub title: Option<String>,
324
325	/// The translator(s) of a work.
326	#[serde(default, skip_serializing_if = "Vec::is_empty")]
327	pub translators: Vec<Name>,
328
329	/// The URL of the work.
330	#[serde(default, skip_serializing_if = "Option::is_none")]
331	pub url: Option<Url>,
332
333	/// The version of the work.
334	#[serde(default, skip_serializing_if = "Option::is_none")]
335	pub version: Option<String>,
336
337	/// The volume of the periodical in which a work appeared.
338	#[serde(default, skip_serializing_if = "Option::is_none")]
339	pub volume: Option<u64>,
340
341	/// The title of the volume in which the work appeared.
342	#[serde(default, skip_serializing_if = "Option::is_none")]
343	pub volume_title: Option<String>,
344
345	/// The year in which a work has been published.
346	#[serde(default, skip_serializing_if = "Option::is_none")]
347	pub year: Option<u64>,
348
349	/// The year of the original publication.
350	#[serde(default, skip_serializing_if = "Option::is_none")]
351	pub year_original: Option<i64>,
352}
353
354/// Publication statuses.
355#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
356#[serde(rename_all = "kebab-case")]
357#[allow(missing_docs)]
358pub enum PublicationStatus {
359	Abstract,
360	AdvanceOnline,
361	InPreparation,
362	InPress,
363	Preprint,
364	Submitted,
365}
366
367/// Types of referenced works.
368#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
369#[serde(rename_all = "kebab-case")]
370#[allow(missing_docs)]
371pub enum RefType {
372	Art,
373	Article,
374	Audiovisual,
375	Bill,
376	Blog,
377	Book,
378	Catalogue,
379	ConferencePaper,
380	Conference,
381	Data,
382	Database,
383	Dictionary,
384	EditedWork,
385	Encyclopedia,
386	FilmBroadcast,
387	Generic,
388	GovernmentDocument,
389	Grant,
390	Hearing,
391	HistoricalWork,
392	LegalCase,
393	LegalRule,
394	MagazineArticle,
395	Manual,
396	Map,
397	Multimedia,
398	Music,
399	NewspaperArticle,
400	Pamphlet,
401	Patent,
402	PersonalCommunication,
403	Proceedings,
404	Report,
405	Serial,
406	Slides,
407	SoftwareCode,
408	SoftwareContainer,
409	SoftwareExecutable,
410	SoftwareVirtualMachine,
411	Software,
412	SoundRecording,
413	Standard,
414	Statute,
415	Thesis,
416	Unpublished,
417	Video,
418	Website,
419}
420
421impl Default for RefType {
422	fn default() -> Self {
423		Self::Generic
424	}
425}