Skip to main content

open_library_api_rs/api/
changes.rs

1// v0.0.1
2use crate::client::OpenLibraryClient;
3use crate::error::Result;
4use crate::models::changes::{ChangesParams, RecentChange};
5use crate::models::common::ChangeKind;
6use crate::validation::{validate_date, validate_limit};
7
8impl OpenLibraryClient {
9    /// Fetch the global recent-changes feed.
10    pub async fn get_recent_changes(
11        &self,
12        params: ChangesParams,
13    ) -> Result<Vec<RecentChange>> {
14        if let Some(l) = params.limit { validate_limit(l)?; }
15        let url = self.build_changes_url("recentchanges.json", params)?;
16        self.get_json(url).await
17    }
18
19    /// Fetch recent changes for a specific date (`YYYY-MM-DD`).
20    pub async fn get_changes_by_date(
21        &self,
22        date: &str,
23        params: ChangesParams,
24    ) -> Result<Vec<RecentChange>> {
25        validate_date(date)?;
26        if let Some(l) = params.limit { validate_limit(l)?; }
27        let parts: Vec<&str> = date.split('-').collect();
28        let path = format!("recentchanges/{}/{}/{}.json", parts[0], parts[1], parts[2]);
29        let url = self.build_changes_url(&path, params)?;
30        self.get_json(url).await
31    }
32
33    /// Fetch recent changes of a specific kind.
34    pub async fn get_changes_by_kind(
35        &self,
36        kind: &ChangeKind,
37        params: ChangesParams,
38    ) -> Result<Vec<RecentChange>> {
39        if let Some(l) = params.limit { validate_limit(l)?; }
40        let path = format!("recentchanges/{}.json", kind.as_str());
41        let url = self.build_changes_url(&path, params)?;
42        self.get_json(url).await
43    }
44
45    /// Fetch recent changes for a specific date and kind.
46    pub async fn get_changes_by_date_and_kind(
47        &self,
48        date: &str,
49        kind: &ChangeKind,
50        params: ChangesParams,
51    ) -> Result<Vec<RecentChange>> {
52        validate_date(date)?;
53        if let Some(l) = params.limit { validate_limit(l)?; }
54        let parts: Vec<&str> = date.split('-').collect();
55        let path = format!(
56            "recentchanges/{}/{}/{}/{}.json",
57            parts[0], parts[1], parts[2],
58            kind.as_str()
59        );
60        let url = self.build_changes_url(&path, params)?;
61        self.get_json(url).await
62    }
63
64    fn build_changes_url(
65        &self,
66        path: &str,
67        params: ChangesParams,
68    ) -> Result<url::Url> {
69        let mut url = self.base_url.join(path)?;
70        if params.limit.is_some() || params.offset.is_some() || params.bot.is_some() {
71            let mut qp = url.query_pairs_mut();
72            if let Some(l) = params.limit { qp.append_pair("limit", &l.to_string()); }
73            if let Some(o) = params.offset { qp.append_pair("offset", &o.to_string()); }
74            if let Some(b) = params.bot {
75                qp.append_pair("bot", if b { "true" } else { "false" });
76            }
77        }
78        Ok(url)
79    }
80}