1use crate::error::{Error, ErrorKind, Result};
2use crate::query::works::{WorksCombiner, WorksFilter, WorksIdentQuery, WorksQuery};
3use crate::query::{Component, CrossrefQuery, CrossrefRoute, ResourceComponent};
4use serde::{Deserialize, Serialize};
5use std::str::FromStr;
6
7#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
9#[serde(tag = "id")]
10#[serde(rename_all = "kebab-case")]
11#[allow(missing_docs)]
12pub enum Type {
13 BookSection,
14 Monograph,
15 Report,
16 PeerReview,
17 BookTrack,
18 JournalArticle,
19 BookPart,
20 Other,
21 Book,
22 JournalVolume,
23 BookSet,
24 ReferenceEntry,
25 ProceedingsArticle,
26 Journal,
27 Component,
28 BookChapter,
29 ProceedingsSeries,
30 ReportSeries,
31 Proceedings,
32 Standard,
33 ReferenceBook,
34 PostedContent,
35 JournalIssue,
36 Dissertation,
37 Dataset,
38 BookSeries,
39 EditedBook,
40 StandardSeries,
41}
42
43impl Type {
44 pub fn label(&self) -> &str {
46 match self {
47 Type::BookSection => "Book Section",
48 Type::Monograph => "Monograph",
49 Type::Report => "Report",
50 Type::PeerReview => "Peer Review",
51 Type::BookTrack => "Book Track",
52 Type::JournalArticle => "Journal Article",
53 Type::BookPart => "Book Part",
54 Type::Other => "Other",
55 Type::Book => "Book",
56 Type::JournalVolume => "Journal Volume",
57 Type::BookSet => "Book Set",
58 Type::ReferenceEntry => "Reference Entry",
59 Type::ProceedingsArticle => "Proceedings Article",
60 Type::Journal => "Journal",
61 Type::Component => "Component",
62 Type::BookChapter => "Book Chapter",
63 Type::ProceedingsSeries => "Proceedings Series",
64 Type::ReportSeries => "Report Series",
65 Type::Proceedings => "Proceedings",
66 Type::Standard => "Standard",
67 Type::ReferenceBook => "Reference Book",
68 Type::PostedContent => "Posted Content",
69 Type::JournalIssue => "Journal Issue",
70 Type::Dissertation => "Dissertation",
71 Type::Dataset => "Dataset",
72 Type::BookSeries => "Book Series",
73 Type::EditedBook => "Edited Book",
74 Type::StandardSeries => "Standard Series",
75 }
76 }
77 pub fn id(&self) -> &str {
79 match self {
80 Type::BookSection => "book-section",
81 Type::Monograph => "monograph",
82 Type::Report => "report",
83 Type::PeerReview => "peer-review",
84 Type::BookTrack => "book-track",
85 Type::JournalArticle => "journal-article",
86 Type::BookPart => "book-part",
87 Type::Other => "other",
88 Type::Book => "book",
89 Type::JournalVolume => "journal-volume",
90 Type::BookSet => "book-set",
91 Type::ReferenceEntry => "reference-entry",
92 Type::ProceedingsArticle => "proceedings-article",
93 Type::Journal => "journal",
94 Type::Component => "component",
95 Type::BookChapter => "book-chapter",
96 Type::ProceedingsSeries => "proceedings-series",
97 Type::ReportSeries => "report-series",
98 Type::Proceedings => "proceedings",
99 Type::Standard => "standard",
100 Type::ReferenceBook => "reference-book",
101 Type::PostedContent => "posted-content",
102 Type::JournalIssue => "journal-issue",
103 Type::Dissertation => "dissertation",
104 Type::Dataset => "dataset",
105 Type::BookSeries => "book-series",
106 Type::EditedBook => "edited-book",
107 Type::StandardSeries => "standard-series",
108 }
109 }
110}
111
112impl FromStr for Type {
113 type Err = Error;
114
115 fn from_str(s: &str) -> Result<Self> {
116 match s {
117 "book-section" => Ok(Type::BookSection),
118 "monograph" => Ok(Type::Monograph),
119 "report" => Ok(Type::Report),
120 "peer-review" => Ok(Type::PeerReview),
121 "book-track" => Ok(Type::BookTrack),
122 "journal-article" => Ok(Type::JournalArticle),
123 "book-part" => Ok(Type::BookPart),
124 "other" => Ok(Type::Other),
125 "book" => Ok(Type::Book),
126 "journal-volume" => Ok(Type::JournalVolume),
127 "book-set" => Ok(Type::BookSet),
128 "reference-entry" => Ok(Type::ReferenceEntry),
129 "proceedings-article" => Ok(Type::ProceedingsArticle),
130 "journal" => Ok(Type::Journal),
131 "component" => Ok(Type::Component),
132 "book-chapter" => Ok(Type::BookChapter),
133 "proceedings-series" => Ok(Type::ProceedingsSeries),
134 "report-series" => Ok(Type::ReportSeries),
135 "proceedings" => Ok(Type::Proceedings),
136 "standard" => Ok(Type::Standard),
137 "reference-book" => Ok(Type::ReferenceBook),
138 "posted-content" => Ok(Type::PostedContent),
139 "journal-issue" => Ok(Type::JournalIssue),
140 "dissertation" => Ok(Type::Dissertation),
141 "dataset" => Ok(Type::Dataset),
142 "book-series" => Ok(Type::BookSeries),
143 "edited-book" => Ok(Type::EditedBook),
144 "standard-series" => Ok(Type::StandardSeries),
145 name => Err(Error::from(ErrorKind::InvalidTypeName {
146 name: name.to_string(),
147 })),
148 }
149 }
150}
151
152#[derive(Debug, Clone)]
154pub enum Types {
155 All,
157 Identifier(String),
159 Works(WorksIdentQuery),
161}
162
163impl CrossrefRoute for Types {
164 fn route(&self) -> Result<String> {
165 match self {
166 Types::All => Component::Types.route(),
167 Types::Identifier(s) => Ok(format!("{}/{}", Component::Types.route()?, s)),
168 Types::Works(combined) => Self::combined_route(combined),
169 }
170 }
171}
172
173impl CrossrefQuery for Types {
174 fn resource_component(self) -> ResourceComponent {
175 ResourceComponent::Types(self)
176 }
177}
178
179#[cfg(test)]
180mod tests {
181 use super::*;
182 use serde_json::*;
183
184 fn test_types() {
186 let section = r#"{
187 "id": "book-section",
188 "label": "Book Section"
189 }"#;
190 let ref_type: Type = serde_json::from_str(section).unwrap();
191
192 assert_eq!(Type::BookSection, ref_type);
193 }
194}