open-library 0.7.1

A client to interact with the Open Library API
Documentation
use crate::clients::handle;
use crate::models::authors::{
    AuthorDetails, AuthorResponse, AuthorWorksRequest, AuthorWorksResponse,
};
use crate::models::identifiers::OpenLibraryIdentifier;
use crate::OpenLibraryError;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::convert::TryInto;
use url::Url;

#[derive(Clone)]
pub struct AuthorClient {
    client: Client,
    host: Url,
}

impl AuthorClient {
    pub fn new(client: &Client, host: &Url) -> Self {
        Self {
            client: client.clone(),
            host: host.clone(),
        }
    }

    pub async fn get(
        &self,
        identifier: OpenLibraryIdentifier,
    ) -> Result<AuthorDetails, OpenLibraryError> {
        let url = self
            .host
            .join(format!("/authors/{}.json", identifier).as_str())?;

        handle(self.client.get(url)).await
    }

    pub async fn get_works<T>(&self, request: T) -> Result<AuthorWorksResponse, OpenLibraryError>
    where
        T: TryInto<AuthorWorksRequest>,
    {
        let parameters: AuthorWorksRequest =
            request
                .try_into()
                .map_err(|_e| OpenLibraryError::ParsingError {
                    reason: format!("Unable to parse supplied object into a proper request object")
                        .to_string(),
                })?;
        let limit = parameters.limit.unwrap_or(50);
        let offset = parameters.offset.unwrap_or(0);
        let url = self.host.join(
            format!(
                "/authors/{}/works.json?limit={}&offset={}",
                parameters.identifier, limit, offset
            )
            .as_str(),
        )?;

        handle(self.client.get(url)).await
    }

    pub async fn search(&self, author_name: &str) -> Result<AuthorResponse, OpenLibraryError> {
        let url = self.host.join("search/authors.json")?;

        handle(
            self.client
                .get(url)
                .query(&[(QueryParameters::AuthorQuery, author_name)]),
        )
        .await
    }
}

#[derive(Deserialize, Serialize)]
enum QueryParameters {
    #[serde(rename = "q")]
    AuthorQuery,
}