1use crate::models::identifiers::OpenLibraryIdentifier;
2use serde::de::Error;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4use std::fmt::{Display, Formatter};
5use std::str::FromStr;
6
7pub mod account;
8pub mod authors;
9pub mod books;
10pub mod identifiers;
11pub mod works;
12
13#[cfg(test)]
14mod tests;
15
16#[derive(Clone, Debug, Eq, PartialEq)]
17pub enum OpenLibraryResource {
18 Author(String),
19 Book(String),
20 Work(String),
21}
22
23impl OpenLibraryResource {
24 pub fn value(&self) -> String {
25 match self {
26 OpenLibraryResource::Author(value) => value,
27 OpenLibraryResource::Book(value) => value,
28 OpenLibraryResource::Work(value) => value,
29 }
30 .clone()
31 }
32}
33
34impl Display for OpenLibraryResource {
35 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
36 let x = match self {
37 OpenLibraryResource::Author(value) => format!("/authors/{}", value),
38 OpenLibraryResource::Book(value) => format!("/books/{}", value),
39 OpenLibraryResource::Work(value) => format!("/works/{}", value),
40 };
41
42 write!(f, "{}", x)?;
43 Ok(())
44 }
45}
46
47impl<'de> Deserialize<'de> for OpenLibraryResource {
48 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
49 where
50 D: Deserializer<'de>,
51 {
52 let value: String = Deserialize::deserialize(deserializer).map_err(D::Error::custom)?;
53
54 let chunks = value
55 .split('/')
56 .filter(|str| !str.is_empty())
57 .collect::<Vec<&str>>();
58
59 let resource = match chunks.get(0) {
60 Some(string) => Ok(*string),
61 None => Err(D::Error::custom(format!(
62 "Supplied identifier string has improper format {}",
63 &value
64 ))),
65 }?;
66
67 let identifier = match chunks.get(1) {
68 Some(string) => Ok(*string),
69 None => Err(D::Error::custom(format!(
70 "Supplied identifier string has improper format {}",
71 &value
72 ))),
73 }?;
74
75 match resource {
76 "authors" => Ok(OpenLibraryResource::Author(identifier.to_string())),
77 "books" => Ok(OpenLibraryResource::Book(identifier.to_string())),
78 "works" => Ok(OpenLibraryResource::Work(identifier.to_string())),
79 _ => Err(D::Error::custom("Could not parse into Resource")),
80 }
81 }
82}
83
84impl Serialize for OpenLibraryResource {
85 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86 where
87 S: Serializer,
88 {
89 serializer.serialize_str(self.to_string().as_str())
90 }
91}
92
93impl From<OpenLibraryResource> for OpenLibraryIdentifier {
94 fn from(resource: OpenLibraryResource) -> Self {
95 Self::from_str(&resource.value()).unwrap()
96 }
97}
98
99#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
100pub struct Link {
101 #[serde(skip_serializing_if = "String::is_empty")]
102 url: String,
103 #[serde(skip_serializing_if = "String::is_empty")]
104 title: String,
105}
106
107#[derive(Clone, Deserialize, Debug, Eq, Hash, PartialEq, Serialize)]
108#[serde(rename_all = "lowercase")]
109pub enum LinkName {
110 Author,
111 #[serde(rename = "self")]
112 Itself,
113 Next,
114}
115
116pub trait OpenLibraryModel {}