1use crate::error::HalError;
2use crate::query::SearchQuery;
3use crate::response::SearchResponse;
4
5pub const DEFAULT_BASE_URL: &str = "https://api.archives-ouvertes.fr/search/";
7
8#[derive(Clone, Debug)]
24pub struct HalClient {
25 base_url: String,
26 http: reqwest::Client,
27}
28
29impl Default for HalClient {
30 fn default() -> Self {
31 Self::new()
32 }
33}
34
35impl HalClient {
36 pub fn new() -> Self {
38 HalClient {
39 base_url: DEFAULT_BASE_URL.to_owned(),
40 http: reqwest::Client::new(),
41 }
42 }
43
44 pub fn with_base_url(base_url: impl Into<String>) -> Self {
46 HalClient {
47 base_url: base_url.into(),
48 http: reqwest::Client::new(),
49 }
50 }
51
52 pub fn base_url(&self) -> &str {
54 &self.base_url
55 }
56
57 pub async fn basic_search(&self, query: &str) -> Result<SearchResponse, HalError> {
59 self.search(&SearchQuery::basic(query)).await
60 }
61
62 pub async fn search(&self, query: &SearchQuery) -> Result<SearchResponse, HalError> {
64 let response = self
65 .http
66 .get(&self.base_url)
67 .query(&query.to_params())
68 .send()
69 .await?;
70
71 let status = response.status();
72 let body = response.text().await?;
73
74 if !status.is_success() {
75 let mut body = body;
76 body.truncate(500);
77 return Err(HalError::Api {
78 status: status.as_u16(),
79 body,
80 });
81 }
82
83 Ok(serde_json::from_str(&body)?)
84 }
85}