open_library_api_rs/api/
search.rs1use crate::client::OpenLibraryClient;
3use crate::error::{Error, Result};
4use crate::models::search::{
5 AuthorDoc, AuthorSearchParams, BookDoc, InsideDoc, ListDoc, SearchParams, SearchResponse,
6 SubjectDoc,
7};
8use crate::validation::{validate_limit, validate_search_query};
9
10impl OpenLibraryClient {
11 pub async fn search(&self, params: SearchParams) -> Result<SearchResponse<BookDoc>> {
19 let q = params.q.as_deref().unwrap_or_default();
21 let title = params.title.as_deref().unwrap_or_default();
22 let author = params.author.as_deref().unwrap_or_default();
23 let isbn = params.isbn.as_deref().unwrap_or_default();
24 let subject = params.subject.as_deref().unwrap_or_default();
25
26 if q.is_empty() && title.is_empty() && author.is_empty() && isbn.is_empty() && subject.is_empty() {
27 return Err(Error::InvalidInput(
28 "at least one of q, title, author, isbn, or subject must be provided".into(),
29 ));
30 }
31 if !q.is_empty() {
32 validate_search_query(q)?;
33 }
34 if let Some(ref limit) = params.limit {
35 validate_limit(*limit)?;
36 }
37
38 let mut url = self.base_url.join("search.json")?;
39 {
40 let mut qp = url.query_pairs_mut();
41 if !q.is_empty() { qp.append_pair("q", q); }
42 if !title.is_empty() { qp.append_pair("title", title); }
43 if !author.is_empty() { qp.append_pair("author", author); }
44 if !isbn.is_empty() { qp.append_pair("isbn", isbn); }
45 if !subject.is_empty() { qp.append_pair("subject", subject); }
46 if let Some(v) = params.place.as_deref() { qp.append_pair("place", v); }
47 if let Some(v) = params.person.as_deref() { qp.append_pair("person", v); }
48 if let Some(v) = params.language.as_deref() { qp.append_pair("language", v); }
49 if let Some(v) = params.publisher.as_deref() { qp.append_pair("publisher", v); }
50 if let Some(v) = params.page { qp.append_pair("page", &v.to_string()); }
51 if let Some(v) = params.limit { qp.append_pair("limit", &v.to_string()); }
52 if let Some(v) = params.offset { qp.append_pair("offset", &v.to_string()); }
53 if let Some(v) = params.sort.as_deref() { qp.append_pair("sort", v); }
54 if let Some(v) = params.fields.as_deref() { qp.append_pair("fields", v); }
55 if let Some(v) = params.lang.as_deref() { qp.append_pair("lang", v); }
56 }
57 self.get_json(url).await
58 }
59
60 pub async fn search_authors(
64 &self,
65 params: AuthorSearchParams,
66 ) -> Result<SearchResponse<AuthorDoc>> {
67 let q = params.q.as_deref().unwrap_or_default();
68 if q.is_empty() {
69 return Err(Error::InvalidInput("author search query must not be empty".into()));
70 }
71 validate_search_query(q)?;
72 if let Some(ref limit) = params.limit {
73 validate_limit(*limit)?;
74 }
75
76 let mut url = self.base_url.join("search/authors.json")?;
77 {
78 let mut qp = url.query_pairs_mut();
79 qp.append_pair("q", q);
80 if let Some(v) = params.limit { qp.append_pair("limit", &v.to_string()); }
81 if let Some(v) = params.offset { qp.append_pair("offset", &v.to_string()); }
82 }
83 self.get_json(url).await
84 }
85
86 pub async fn search_subjects(&self, query: &str) -> Result<SearchResponse<SubjectDoc>> {
90 validate_search_query(query)?;
91 let mut url = self.base_url.join("search/subjects.json")?;
92 url.query_pairs_mut().append_pair("q", query);
93 self.get_json(url).await
94 }
95
96 pub async fn search_lists(&self, query: &str, limit: Option<u32>) -> Result<SearchResponse<ListDoc>> {
100 validate_search_query(query)?;
101 if let Some(l) = limit { validate_limit(l)?; }
102 let mut url = self.base_url.join("search/lists.json")?;
103 {
104 let mut qp = url.query_pairs_mut();
105 qp.append_pair("q", query);
106 if let Some(l) = limit { qp.append_pair("limit", &l.to_string()); }
107 }
108 self.get_json(url).await
109 }
110
111 pub async fn search_inside(
115 &self,
116 query: &str,
117 limit: Option<u32>,
118 ) -> Result<SearchResponse<InsideDoc>> {
119 validate_search_query(query)?;
120 if let Some(l) = limit { validate_limit(l)?; }
121 let mut url = self.base_url.join("search/inside.json")?;
122 {
123 let mut qp = url.query_pairs_mut();
124 qp.append_pair("q", query);
125 if let Some(l) = limit { qp.append_pair("limit", &l.to_string()); }
126 }
127 self.get_json(url).await
128 }
129}