openlibrary_rs/
books.rs

1use std::fmt::Display;
2
3use derive_builder::Builder;
4
5use crate::OpenlibraryRequest;
6
7#[derive(Default, Clone, Debug)]
8pub enum BookType {
9    #[default]
10    Works,
11    Editions,
12    ISBN,
13}
14
15impl Display for BookType {
16    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
17        write!(
18            f,
19            "{}",
20            match self {
21                Self::Works => "/works",
22                Self::Editions => "/books",
23                Self::ISBN => "/isbn",
24            }
25        )
26    }
27}
28
29/// The struct representation of a request to the [Books API](https://openlibrary.org/dev/docs/api/books)
30///
31/// The fields of this struct are private. If you want to view available fields that can be set please look at the [`BooksBuilder`] struct.
32#[derive(Builder, Default, Debug)]
33#[builder(setter(into), default)]
34pub struct Books {
35    book_type: BookType,
36    id: String,
37}
38
39impl OpenlibraryRequest for Books {
40    fn path(&self) -> String {
41        format!("{}/{}.json", self.book_type, self.id)
42    }
43
44    fn query(&self) -> Vec<(&'static str, String)> {
45        vec![]
46    }
47}
48
49/// The struct representation of a request to the generic [Books API](https://openlibrary.org/dev/docs/api/books)
50///
51/// The fields of this struct are private. If you want to view available fields that can be set please look at the [`BooksGenericBuilder`] struct.
52#[derive(Builder, Default, Debug)]
53#[builder(setter(into), default)]
54pub struct BooksGeneric {
55    #[builder(default = "vec![]")]
56    bibkeys: Vec<String>,
57    #[builder(default = r#"String::from("viewapi")"#)]
58    jscmd: String,
59}
60
61impl OpenlibraryRequest for BooksGeneric {
62    fn path(&self) -> String {
63        String::from("/api/books")
64    }
65
66    fn query(&self) -> Vec<(&'static str, String)> {
67        vec![
68            ("format", String::from("json")),
69            ("bibkeys", self.bibkeys.join(",")),
70            ("jscmd", self.jscmd.clone()),
71        ]
72    }
73}
74
75#[cfg(test)]
76mod tests {
77    use mockito::{mock, Matcher};
78    use serde_json::json;
79
80    use crate::OpenlibraryRequest;
81
82    use super::{BooksBuilder, BooksGenericBuilder};
83
84    #[test]
85    fn test_books_execute() {
86        let books = BooksBuilder::default().id("1234").build().unwrap();
87
88        let json = json!({
89            "title": "test",
90            "description": "this is a test",
91            "key": "/works/1234"
92        });
93
94        let _m = mock("GET", Matcher::Regex(format!(r"{}\w*", books.url().path())))
95            .with_header("content-type", "application/json")
96            .with_body(json.to_string())
97            .create();
98
99        let books_result = books.execute();
100
101        assert_eq!(books_result["title"], "test");
102        assert_eq!(books_result["description"], "this is a test");
103        assert_eq!(books_result["key"], "/works/1234");
104    }
105
106    #[test]
107    fn test_books_generic_execute() {
108        let books_generic = BooksGenericBuilder::default()
109            .bibkeys(vec!["ISBN:0385472579".to_string()])
110            .build()
111            .unwrap();
112
113        let json = json!({
114            "ISBN:0385472579": {
115                "bib_key": "ISBN:0385472579",
116                "preview": "noview",
117                "thumbnail_url": "https://covers.openlibrary.org/b/id/240726-S.jpg",
118                "preview_url": "https://openlibrary.org/books/OL1397864M/Zen_speaks",
119                "info_url": "https://openlibrary.org/books/OL1397864M/Zen_speaks"
120            }
121        });
122
123        let _m = mock(
124            "GET",
125            Matcher::Regex(format!(r"{}\w*", books_generic.url().path())),
126        )
127        .with_header("content-type", "application/json")
128        .with_body(json.to_string())
129        .create();
130
131        let result = books_generic.execute();
132        let inner_result = &result["ISBN:0385472579"];
133
134        assert_eq!(inner_result["bib_key"], "ISBN:0385472579");
135        assert_eq!(inner_result["preview"], "noview");
136        assert_eq!(
137            inner_result["thumbnail_url"],
138            "https://covers.openlibrary.org/b/id/240726-S.jpg"
139        );
140        assert_eq!(
141            inner_result["preview_url"],
142            "https://openlibrary.org/books/OL1397864M/Zen_speaks"
143        );
144        assert_eq!(
145            inner_result["info_url"],
146            "https://openlibrary.org/books/OL1397864M/Zen_speaks"
147        );
148    }
149}