citeworks-cff 0.1.1

Serde types for serialising and deserialising CFF (Citation File Format)
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
//! Types and utilities for references to this or other works.

use serde::{Deserialize, Serialize};
use url::Url;

use crate::{
	identifiers::Identifier,
	names::{EntityName, Name},
	Date, License,
};

/// A reference for a work.
#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub struct Reference {
	/// The type of the referenced work.
	///
	/// This is required.
	#[serde(rename = "type")]
	pub work_type: RefType,

	/// The authors of the work.
	///
	/// This is required and must contain at least one author.
	pub authors: Vec<Name>,

	/// The abbreviation of a work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub abbreviation: Option<String>,

	/// The abstract of the work.
	///
	/// - If the work is a journal paper or other academic work,
	///   The abstract of the work.
	///
	/// - If the work is a film broadcast or similar,
	///   The synopsis of the work.
	#[serde(default, skip_serializing_if = "Option::is_none", rename = "abstract")]
	pub abstract_text: Option<String>,

	/// The DOI of a collection containing the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub collection_doi: Option<String>,

	/// The title of a collection or proceedings.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub collection_title: Option<String>,

	/// The type of a collection.
	///
	/// By convention this should be in lowercase.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub collection_type: Option<String>,

	/// The commit hash or revision number of the work, if it is software.
	///
	/// By convention:
	/// - if this is a Git hash, it should be bare lowercase hex, e.g.
	///   `1ff847d81f29c45a3a1a5ce73d38e45c2f319bba`;
	/// - if this is a decimal revision or build number, it should be preceded
	///   by a label, e.g. `Revision: 8612`.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub commit: Option<String>,

	/// The conference where the work was presented.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub conference: Option<EntityName>,

	/// The contact person, group, company, etc. for a work.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub contact: Vec<Name>,

	/// The copyright information pertaining to the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub copyright: Option<String>,

	/// The data type of a data set.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub data_type: Option<String>,

	/// The provider of the database where a work was accessed/is stored.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub database_provider: Option<EntityName>,

	/// The name of the database where a work was accessed/is stored.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub database: Option<String>,

	/// The date the work was accessed.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub date_accessed: Option<Date>,

	/// The date the work has been downloaded.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub date_downloaded: Option<Date>,

	/// The date the work has been published.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub date_published: Option<Date>,

	/// The date the work has been released.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub date_released: Option<Date>,

	/// The department where a work has been produced.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub department: Option<String>,

	/// The DOI of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub doi: Option<String>,

	/// The edition of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub edition: Option<String>,

	/// The editor(s) of a work.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub editors: Vec<Name>,

	/// The editor(s) of a series in which the work has been published.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub editors_series: Vec<Name>,

	/// The start page of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub start: Option<u64>,

	/// The end page of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub end: Option<u64>,

	/// An entry in the collection that constitutes the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub entry: Option<String>,

	/// The name of the electronic file containing the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub filename: Option<String>,

	/// The format in which a work is represented.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub format: Option<String>,

	/// The identifier(s) of the work.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub identifiers: Vec<Identifier>,

	/// The institution where a work has been produced or published.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub institution: Option<EntityName>,

	/// The [ISBN] of the work.
	///
	/// The value is not validated.
	///
	/// [ISBN]: https://en.wikipedia.org/wiki/International_Standard_Book_Number
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub isbn: Option<String>,

	/// The [ISSN] of the work.
	///
	/// The value is not validated.
	///
	/// [ISSN]: https://en.wikipedia.org/wiki/International_Standard_Serial_Number
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub issn: Option<String>,

	/// The issue of a periodical in which a work appeared.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub issue: Option<String>,

	/// The publication date of the issue of a periodical in which a work appeared.
	///
	/// Note this is a freeform string.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub issue_date: Option<String>,

	/// The name of the issue of a periodical in which the work appeared.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub issue_title: Option<String>,

	/// The name of the journal/magazine/newspaper/periodical where the work was published.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub journal: Option<String>,

	/// Keywords pertaining to the work.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub keywords: Vec<String>,

	/// The language identifier(s) of the work.
	///
	/// These should be ISO639 strings in lowercase alpha-2 or alpha-3, but this
	/// library does not validate this.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub languages: Vec<String>,

	/// [SPDX][spdx] license expression(s).
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub license: Option<License>,

	/// The URL of the license text under which the work is licensed.
	///
	/// This should only be used for non-standard licenses not included in the
	/// SPDX License List.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub license_url: Option<Url>,

	/// The line of code in the file where the work ends.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub loc_end: Option<u64>,

	/// The line of code in the file where the work starts.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub loc_start: Option<u64>,

	/// The location of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub location: Option<EntityName>,

	/// The medium of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub medium: Option<String>,

	/// The month in which a work has been published.
	///
	/// Should be an integer in the range 1-12. Note this is not validated.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub month: Option<u8>,

	/// The [NIHMSID] of a work.
	///
	/// [NIHMSID]: https://web.archive.org/web/20210802210057/https://www.ncbi.nlm.nih.gov/pmc/about/public-access-info/
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub nihmsid: Option<String>,

	/// Notes pertaining to the work.
	///
	/// Note that this key should contain notes that may be picked up by some
	/// downstream tooling (e.g., reference managers), but not others
	/// (e.g., a software index).
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub notes: Option<String>,

	/// The (library) [accession number] for a work.
	///
	/// [accession number]: https://en.wikipedia.org/wiki/Accession_number
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub number: Option<String>,

	/// The number of volumes making up the collection in which the work has
	/// been published.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub number_volumes: Option<u64>,

	/// The number of pages of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub pages: Option<u64>,

	/// The states for which a patent is granted.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub patent_states: Vec<String>,

	/// The [PMCID] of a work.
	///
	/// The value is not validated.
	///
	/// [PMCID]: https://web.archive.org/web/20210802210057/https://www.ncbi.nlm.nih.gov/pmc/about/public-access-info/
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub pmcid: Option<String>,

	/// The publisher who has published the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub publisher: Option<EntityName>,

	/// The recipient(s) of a personal communication.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub recipients: Vec<Name>,

	/// The URL of the work in a repository/archive.
	///
	/// This is to be used when the repository is neither a source code
	/// repository nor a build artifact repository. For source code, use the
	/// `repository_code` field; for binary releases or other built forms, use
	/// the `repository_artifact` field.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub repository: Option<Url>,

	/// The URL of the work in a build artifact/binary repository.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub repository_artifact: Option<Url>,

	/// The URL of the work in a source code repository.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub repository_code: Option<Url>,

	/// The scope of the reference, e.g., the section of the work it adheres to.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub scope: Option<String>,

	/// The section of a work that is referenced.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub section: Option<String>,

	/// The sender(s) of a personal communication.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub senders: Vec<Name>,

	/// The publication status of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub status: Option<PublicationStatus>,

	/// The term being referenced if the work is a dictionary or encyclopedia.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub term: Option<String>,

	/// The type of the thesis that is the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub thesis_type: Option<String>,

	/// The title of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub title: Option<String>,

	/// The translator(s) of a work.
	#[serde(default, skip_serializing_if = "Vec::is_empty")]
	pub translators: Vec<Name>,

	/// The URL of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub url: Option<Url>,

	/// The version of the work.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub version: Option<String>,

	/// The volume of the periodical in which a work appeared.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub volume: Option<u64>,

	/// The title of the volume in which the work appeared.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub volume_title: Option<String>,

	/// The year in which a work has been published.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub year: Option<u64>,

	/// The year of the original publication.
	#[serde(default, skip_serializing_if = "Option::is_none")]
	pub year_original: Option<i64>,
}

/// Publication statuses.
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[allow(missing_docs)]
pub enum PublicationStatus {
	Abstract,
	AdvanceOnline,
	InPreparation,
	InPress,
	Preprint,
	Submitted,
}

/// Types of referenced works.
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[allow(missing_docs)]
pub enum RefType {
	Art,
	Article,
	Audiovisual,
	Bill,
	Blog,
	Book,
	Catalogue,
	ConferencePaper,
	Conference,
	Data,
	Database,
	Dictionary,
	EditedWork,
	Encyclopedia,
	FilmBroadcast,
	Generic,
	GovernmentDocument,
	Grant,
	Hearing,
	HistoricalWork,
	LegalCase,
	LegalRule,
	MagazineArticle,
	Manual,
	Map,
	Multimedia,
	Music,
	NewspaperArticle,
	Pamphlet,
	Patent,
	PersonalCommunication,
	Proceedings,
	Report,
	Serial,
	Slides,
	SoftwareCode,
	SoftwareContainer,
	SoftwareExecutable,
	SoftwareVirtualMachine,
	Software,
	SoundRecording,
	Standard,
	Statute,
	Thesis,
	Unpublished,
	Video,
	Website,
}

impl Default for RefType {
	fn default() -> Self {
		Self::Generic
	}
}