Skip to main content

open_library_api_rs/models/
common.rs

1// v0.0.1
2use serde::{Deserialize, Serialize};
3
4/// A reference to an Open Library resource, e.g. `{ "key": "/works/OL45804W" }`.
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub struct Key {
7    pub key: String,
8}
9
10/// A typed reference that also carries the object type name.
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub struct TypedKey {
13    pub key: String,
14    #[serde(rename = "type")]
15    pub kind: String,
16}
17
18/// A hyperlink with a URL and optional title.
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct Link {
21    pub url: String,
22    #[serde(default)]
23    pub title: Option<String>,
24}
25
26/// A value that Open Library sometimes returns as a plain string and sometimes as
27/// `{ "value": "..." }`. Use `TextOrValue::into_text()` to normalise.
28#[derive(Debug, Clone, Serialize, Deserialize)]
29#[serde(untagged)]
30pub enum TextOrValue {
31    Text(String),
32    Value { value: String },
33}
34
35impl TextOrValue {
36    pub fn into_text(self) -> String {
37        match self {
38            TextOrValue::Text(s) => s,
39            TextOrValue::Value { value } => value,
40        }
41    }
42
43    pub fn as_str(&self) -> &str {
44        match self {
45            TextOrValue::Text(s) => s.as_str(),
46            TextOrValue::Value { value } => value.as_str(),
47        }
48    }
49}
50
51/// An integer that Open Library sometimes wraps as `{ "value": 123 }`.
52#[derive(Debug, Clone, Serialize, Deserialize)]
53#[serde(untagged)]
54pub enum IntOrValue {
55    Int(i64),
56    Value { value: i64 },
57}
58
59impl IntOrValue {
60    pub fn value(&self) -> i64 {
61        match self {
62            IntOrValue::Int(n) => *n,
63            IntOrValue::Value { value } => *value,
64        }
65    }
66}
67
68/// Pagination links returned in some list-style responses.
69#[derive(Debug, Clone, Serialize, Deserialize)]
70pub struct PaginationLinks {
71    #[serde(rename = "self")]
72    pub self_url: Option<String>,
73    pub next: Option<String>,
74    pub prev: Option<String>,
75}
76
77/// Cover / photo image sizes.
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
79pub enum ImageSize {
80    #[serde(rename = "S")]
81    Small,
82    #[serde(rename = "M")]
83    Medium,
84    #[serde(rename = "L")]
85    Large,
86}
87
88impl ImageSize {
89    pub fn as_str(self) -> &'static str {
90        match self {
91            ImageSize::Small => "S",
92            ImageSize::Medium => "M",
93            ImageSize::Large => "L",
94        }
95    }
96}
97
98/// The key type used when querying covers.
99#[derive(Debug, Clone, Copy, PartialEq, Eq)]
100pub enum CoverKey {
101    /// Internal numeric cover ID.
102    Id,
103    Isbn,
104    Oclc,
105    Lccn,
106    Olid,
107}
108
109impl CoverKey {
110    pub fn as_str(self) -> &'static str {
111        match self {
112            CoverKey::Id => "id",
113            CoverKey::Isbn => "isbn",
114            CoverKey::Oclc => "oclc",
115            CoverKey::Lccn => "lccn",
116            CoverKey::Olid => "olid",
117        }
118    }
119}
120
121/// Identifier type used by the Partner (Volumes) API.
122#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub enum VolumeIdType {
124    Isbn,
125    Lccn,
126    Oclc,
127    Olid,
128}
129
130impl VolumeIdType {
131    pub fn as_str(self) -> &'static str {
132        match self {
133            VolumeIdType::Isbn => "isbn",
134            VolumeIdType::Lccn => "lccn",
135            VolumeIdType::Oclc => "oclc",
136            VolumeIdType::Olid => "olid",
137        }
138    }
139}
140
141/// Kind of change in the Recent Changes API.
142#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
143#[serde(rename_all = "kebab-case")]
144pub enum ChangeKind {
145    AddCover,
146    AddBook,
147    EditBook,
148    MergeAuthors,
149    Update,
150    Revert,
151    NewAccount,
152    Register,
153    Lists,
154    #[serde(other)]
155    Other,
156}
157
158impl ChangeKind {
159    pub fn as_str(&self) -> &str {
160        match self {
161            ChangeKind::AddCover => "add-cover",
162            ChangeKind::AddBook => "add-book",
163            ChangeKind::EditBook => "edit-book",
164            ChangeKind::MergeAuthors => "merge-authors",
165            ChangeKind::Update => "update",
166            ChangeKind::Revert => "revert",
167            ChangeKind::NewAccount => "new-account",
168            ChangeKind::Register => "register",
169            ChangeKind::Lists => "lists",
170            ChangeKind::Other => "other",
171        }
172    }
173}
174
175/// Reading shelf identifier.
176#[derive(Debug, Clone, Copy, PartialEq, Eq)]
177pub enum ReadingShelf {
178    WantToRead,
179    CurrentlyReading,
180    AlreadyRead,
181}
182
183impl ReadingShelf {
184    pub fn as_str(self) -> &'static str {
185        match self {
186            ReadingShelf::WantToRead => "want-to-read",
187            ReadingShelf::CurrentlyReading => "currently-reading",
188            ReadingShelf::AlreadyRead => "already-read",
189        }
190    }
191}
192
193/// Sort order for search.
194#[derive(Debug, Clone, Copy, PartialEq, Eq)]
195pub enum SortOrder {
196    Relevance,
197    NewestFirst,
198    OldestFirst,
199}
200
201impl SortOrder {
202    pub fn as_str(self) -> &'static str {
203        match self {
204            SortOrder::Relevance => "relevance",
205            SortOrder::NewestFirst => "new",
206            SortOrder::OldestFirst => "old",
207        }
208    }
209}
210
211/// `jscmd` parameter for the `/api/books` endpoint.
212#[derive(Debug, Clone, Copy, PartialEq, Eq)]
213pub enum BooksJsCmd {
214    Data,
215    Details,
216    ViewApi,
217}
218
219impl BooksJsCmd {
220    pub fn as_str(self) -> &'static str {
221        match self {
222            BooksJsCmd::Data => "data",
223            BooksJsCmd::Details => "details",
224            BooksJsCmd::ViewApi => "viewapi",
225        }
226    }
227}