open-library-api-rs 0.1.0

Async Rust client for the Open Library API
Documentation
// v0.0.1
use crate::client::OpenLibraryClient;
use crate::error::Result;
use crate::models::changes::{ChangesParams, RecentChange};
use crate::models::common::ChangeKind;
use crate::validation::{validate_date, validate_limit};

impl OpenLibraryClient {
    /// Fetch the global recent-changes feed.
    pub async fn get_recent_changes(
        &self,
        params: ChangesParams,
    ) -> Result<Vec<RecentChange>> {
        if let Some(l) = params.limit { validate_limit(l)?; }
        let url = self.build_changes_url("recentchanges.json", params)?;
        self.get_json(url).await
    }

    /// Fetch recent changes for a specific date (`YYYY-MM-DD`).
    pub async fn get_changes_by_date(
        &self,
        date: &str,
        params: ChangesParams,
    ) -> Result<Vec<RecentChange>> {
        validate_date(date)?;
        if let Some(l) = params.limit { validate_limit(l)?; }
        let parts: Vec<&str> = date.split('-').collect();
        let path = format!("recentchanges/{}/{}/{}.json", parts[0], parts[1], parts[2]);
        let url = self.build_changes_url(&path, params)?;
        self.get_json(url).await
    }

    /// Fetch recent changes of a specific kind.
    pub async fn get_changes_by_kind(
        &self,
        kind: &ChangeKind,
        params: ChangesParams,
    ) -> Result<Vec<RecentChange>> {
        if let Some(l) = params.limit { validate_limit(l)?; }
        let path = format!("recentchanges/{}.json", kind.as_str());
        let url = self.build_changes_url(&path, params)?;
        self.get_json(url).await
    }

    /// Fetch recent changes for a specific date and kind.
    pub async fn get_changes_by_date_and_kind(
        &self,
        date: &str,
        kind: &ChangeKind,
        params: ChangesParams,
    ) -> Result<Vec<RecentChange>> {
        validate_date(date)?;
        if let Some(l) = params.limit { validate_limit(l)?; }
        let parts: Vec<&str> = date.split('-').collect();
        let path = format!(
            "recentchanges/{}/{}/{}/{}.json",
            parts[0], parts[1], parts[2],
            kind.as_str()
        );
        let url = self.build_changes_url(&path, params)?;
        self.get_json(url).await
    }

    fn build_changes_url(
        &self,
        path: &str,
        params: ChangesParams,
    ) -> Result<url::Url> {
        let mut url = self.base_url.join(path)?;
        if params.limit.is_some() || params.offset.is_some() || params.bot.is_some() {
            let mut qp = url.query_pairs_mut();
            if let Some(l) = params.limit { qp.append_pair("limit", &l.to_string()); }
            if let Some(o) = params.offset { qp.append_pair("offset", &o.to_string()); }
            if let Some(b) = params.bot {
                qp.append_pair("bot", if b { "true" } else { "false" });
            }
        }
        Ok(url)
    }
}