From 5b2657010c47a2819929eb45907596f28319e968 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Sat, 23 Oct 2021 19:50:23 +0500 Subject: [PATCH] Rewrite client --- examples/client.rs | 18 +++++++++++++ src/client.rs | 66 +++++++++++++++++++++++++++++++++++++--------- src/lib.rs | 4 +-- 3 files changed, 74 insertions(+), 14 deletions(-) create mode 100644 examples/client.rs diff --git a/examples/client.rs b/examples/client.rs new file mode 100644 index 0000000..0ad300c --- /dev/null +++ b/examples/client.rs @@ -0,0 +1,18 @@ +/* + * This example uses fake JSON:API + * https://jsonapiplayground.reyesoft.com + */ + +use jsonapis::{Client, Document, Response}; + +fn main() { + let client = Client::new("https://jsonapiplayground.reyesoft.com/v2"); + + let response: Response = client + .get("/stores", &[("filter[created_by]", "1,3".to_string())]) + .unwrap(); + + let document: &Document = response.document(); + + println!("{:#?}", document); +} diff --git a/src/client.rs b/src/client.rs index c893439..9b93571 100644 --- a/src/client.rs +++ b/src/client.rs @@ -15,7 +15,10 @@ const MIME: &str = "application/vnd.api+json"; const MIME_PREFIX: &str = "application/vnd.api+json;"; #[derive(Clone, Debug)] -pub struct Client(String); +pub struct Client { + url: String, + add_json_ext: bool, +} pub type Result = std::result::Result; @@ -46,7 +49,17 @@ impl Response { impl Client { pub fn new>(url: U) -> Self { - Self(url.into()) + Self { + url: url.into(), + add_json_ext: false, + } + } + + pub fn add_json_ext(self, add_json_ext: bool) -> Self { + Self { + add_json_ext, + ..self + } } pub fn get(&self, path: P, params: I) -> Result @@ -57,9 +70,7 @@ impl Client { V: AsRef, ::Item: std::borrow::Borrow<(K, V)>, { - let url = - Url::parse_with_params(&format!("{}{}.json", self.0, path), params) - .map_err(|error| Error::URL(error))?; + let url = self.url_for_get(path, params).map_err(Error::URL)?; let (status, response) = Self::make_request(ReqClient::new().get(url))?; @@ -82,8 +93,7 @@ impl Client { P: Display, D: Into<&'d Document>, { - let url = Url::parse(&format!("{}{}.json", self.0, path)) - .map_err(|error| Error::URL(error))?; + let url = self.url_for_post(path).map_err(Error::URL)?; let document: &Document = document.into(); @@ -106,14 +116,47 @@ impl Client { } } - fn make_request<'a>( + fn url_for_get( + &self, + path: P, + params: I, + ) -> std::result::Result + where + P: Display, + I: IntoIterator, + K: AsRef, + V: AsRef, + ::Item: std::borrow::Borrow<(K, V)>, + { + Url::parse_with_params( + &if self.add_json_ext { + format!("{}{}.json", self.url, path) + } else { + format!("{}{}", self.url, path) + }, + params, + ) + } + + fn url_for_post

(&self, path: P) -> std::result::Result + where + P: Display, + { + Url::parse(&if self.add_json_ext { + format!("{}{}.json", self.url, path) + } else { + format!("{}{}", self.url, path) + }) + } + + fn make_request( request_builder: RequestBuilder, ) -> std::result::Result<(StatusCode, Response), Error> { let response = request_builder .header(ACCEPT, MIME) .header(CONTENT_TYPE, MIME) .send() - .map_err(|error| Error::HTTP(error))?; + .map_err(Error::HTTP)?; let status = response.status(); @@ -136,10 +179,9 @@ impl Client { }, }; - let json = response.text().map_err(|error| Error::Text(error))?; + let json = response.text().map_err(Error::Text)?; - let document = - serde_json::from_str(&json).map_err(|error| Error::JSON(error))?; + let document = serde_json::from_str(&json).map_err(Error::JSON)?; Ok((status, Response { document, location })) } diff --git a/src/lib.rs b/src/lib.rs index b3eb231..1d9d72d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ mod builders; -#[cfg(client)] +#[cfg(feature = "client")] mod client; mod entities; pub use builders::*; -#[cfg(client)] +#[cfg(feature = "client")] pub use client::*; pub use entities::*;