openlibrary_rs/
lib.rs

1//! Wrapper for [Openlibrary's Web API](https://openlibrary.org/developers/api)
2//!
3//! # Overview
4//!
5//! **PLEASE NOTE**: this crate is currently in an experimental stage.
6//! Meaning expect frequent, large breaking changes from version to version until we are in a stable state.
7//!
8//! There are currently 8 sub APIs offered by Openlibrary's Web API.
9//! You can check the table below to see the status of each.
10//!
11//! - [X] [Books](https://openlibrary.org/dev/docs/api/books)
12//! - [X] [Authors](https://openlibrary.org/dev/docs/api/authors)
13//! - [ ] [Subjects](https://openlibrary.org/dev/docs/api/subjects)
14//! - [X] [Search](https://openlibrary.org/dev/docs/api/search)
15//! - [ ] [Search inside](https://openlibrary.org/dev/docs/api/search_inside)
16//! - [ ] [Partner](https://openlibrary.org/dev/docs/api/read)
17//! - [ ] [Covers](https://openlibrary.org/dev/docs/api/covers)
18//! - [ ] [Recent Changes](https://openlibrary.org/dev/docs/api/recentchanges)
19//!
20//! # Books
21//!
22//! You can view information about books by Works, Editions, and ISBN ids by using the [`books::Books`] struct
23//!
24//! ``` rust
25//! use openlibrary_rs::books::{BookType, BooksBuilder};
26//! use openlibrary_rs::OpenlibraryRequest;
27//!
28//! let books = BooksBuilder::default()
29//!     .book_type(BookType::Works)
30//!     .id("OL45883W")
31//!     .build()
32//!     .unwrap();
33//!
34//!     println!("{:#?}", books.execute());
35//! ```
36//!
37//! You can view information about multiple books by using the [`books::BooksGeneric`] struct
38//!
39//! ``` rust
40//! use openlibrary_rs::books::{BookType, BooksGenericBuilder};
41//! use openlibrary_rs::OpenlibraryRequest;
42//!
43//! let books_generic = BooksGenericBuilder::default()
44//!     .bibkeys(vec![
45//!         "ISBN:0201558025".to_string(),
46//!         "LCCN:93005405".to_string(),
47//!     ])
48//!     .build()
49//!     .unwrap();
50//!
51//! println!("{:#?}", books_generic.execute());
52//! ```
53//!
54//! # Authors
55//!
56//! You can view information about authors or their works by using the [`authors::Authors`] struct
57//!
58//! ``` rust
59//! use openlibrary_rs::{authors::AuthorsBuilder, OpenlibraryRequest};
60//!
61//! let authors = AuthorsBuilder::default().id("OL23919A").build().unwrap();
62//!
63//! println!("{:#?}", authors.execute());
64//! ```
65//!
66//! # Search
67//!
68//! You can search for books, authors, and more using the [`search::Search`] struct
69//!
70//! ``` rust
71//! use openlibrary_rs::search::SearchBuilder;
72//! use openlibrary_rs::OpenlibraryRequest;
73//!
74//! let search = SearchBuilder::default()
75//!     .query("the lord of the rings")
76//!     .build()
77//!     .unwrap();
78//!
79//! println!("{:#?}", search.execute());
80//! ```
81//!
82use reqwest::Url;
83use serde_json::Value;
84
85#[allow(dead_code)]
86const OPENLIBRARY_HOST: &str = "https://openlibrary.org";
87
88pub mod authors;
89pub mod books;
90pub mod search;
91
92/// Trait representation of an Openlibrary request
93pub trait OpenlibraryRequest {
94    fn host() -> String {
95        #[cfg(not(test))]
96        return OPENLIBRARY_HOST.to_string();
97        #[cfg(test)]
98        return mockito::server_url();
99    }
100
101    fn path(&self) -> String;
102
103    fn query(&self) -> Vec<(&'static str, String)>;
104
105    fn url(&self) -> Url {
106        Url::parse_with_params(
107            format!("{}{}", Self::host(), self.path()).as_str(),
108            self.query(),
109        )
110        .unwrap()
111    }
112
113    fn execute(&self) -> Value {
114        let response = reqwest::blocking::get(self.url()).unwrap();
115        response.json().unwrap()
116    }
117}