From 700784446fb72d854946a369aa3f21543350172b Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 30 Jul 2020 21:00:09 +0200 Subject: [PATCH 1/7] General working client, small kinks to solve still --- graphql_client/Cargo.toml | 64 ++++---- graphql_client/src/client.rs | 74 +++++++++ graphql_client/src/lib.rs | 6 +- graphql_client/src/web.rs | 155 ------------------ graphql_client/tests/client.rs | 93 +++++++++++ graphql_client/tests/countries_schema.graphql | 77 +++++++++ graphql_client/tests/web.rs | 100 ----------- 7 files changed, 275 insertions(+), 294 deletions(-) create mode 100644 graphql_client/src/client.rs delete mode 100644 graphql_client/src/web.rs create mode 100644 graphql_client/tests/client.rs create mode 100644 graphql_client/tests/countries_schema.graphql delete mode 100644 graphql_client/tests/web.rs diff --git a/graphql_client/Cargo.toml b/graphql_client/Cargo.toml index 282c6db63..2f088edd2 100644 --- a/graphql_client/Cargo.toml +++ b/graphql_client/Cargo.toml @@ -1,68 +1,60 @@ [package] -name = "graphql_client" -version = "0.9.0" authors = ["Tom Houlé "] -description = "Typed GraphQL requests and responses" -repository = "https://github.com/graphql-rust/graphql-client" -license = "Apache-2.0 OR MIT" -keywords = ["graphql", "api", "web", "webassembly", "wasm"] categories = ["network-programming", "web-programming", "wasm"] +description = "Typed GraphQL requests and responses" edition = "2018" +keywords = ["graphql", "api", "web", "webassembly", "wasm"] +license = "Apache-2.0 OR MIT" +name = "graphql_client" +repository = "https://github.com/graphql-rust/graphql-client" +version = "0.9.0" [dependencies] +anyhow = {version = "1.0", optional = true} doc-comment = "^0.3" -anyhow = { version = "1.0", optional = true } -thiserror = { version = "1.0", optional = true } -graphql_query_derive = { path = "../graphql_query_derive", version = "0.9.0" } +graphql_query_derive = {path = "../graphql_query_derive", version = "0.9.0"} +reqwest = {version = "0.10.7", optional = true} +serde = {version = "^1.0.78", features = ["derive"]} serde_json = "1.0" -serde = { version = "^1.0.78", features = ["derive"] } +thiserror = {version = "1.0", optional = true} [dependencies.futures] -version = "^0.1" optional = true +version = "^0.1" [dependencies.js-sys] -version = "^0.3" optional = true +version = "^0.3" [dependencies.log] -version = "^0.4" optional = true +version = "^0.4" [dependencies.web-sys] -version = "^0.3" -optional = true features = [ - "Headers", - "Request", - "RequestInit", - "Response", - "Window", + "Headers", + "Request", + "RequestInit", + "Response", + "Window", ] +optional = true +version = "^0.3" [dependencies.wasm-bindgen] -version = "^0.2" optional = true +version = "^0.2" [dependencies.wasm-bindgen-futures] -version = "^0.3" optional = true - -[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -reqwest = "^0.9" +version = "^0.4" [dev-dependencies] +tokio = {version = "^0.2", features = ["rt-threaded", "macros"]} # Note: If we bumpup wasm-bindge-test version, we should change CI setting. -wasm-bindgen-test = "^0.2" +wasm-bindgen-test = "^0.3" [features] -web = [ - "anyhow", - "thiserror", - "futures", - "js-sys", - "log", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] +client = ["reqwest"] +default = ["client"] +web = [] diff --git a/graphql_client/src/client.rs b/graphql_client/src/client.rs new file mode 100644 index 000000000..b6d88bfb0 --- /dev/null +++ b/graphql_client/src/client.rs @@ -0,0 +1,74 @@ +//! Some global + +use crate::*; +use std::collections::HashMap; + +/// The main interface to the library. +/// +/// The workflow is the following: +/// +/// - create a client +/// - (optionally) configure it +/// - use it to perform queries with the [call] method +pub struct Client { + endpoint: String, + headers: HashMap, + reqwest_client: reqwest::Client, +} + +impl Client { + /// Initialize a client. The `endpoint` parameter is the URI of the GraphQL API. + pub fn new(endpoint: Endpoint) -> Client + where + Endpoint: Into, + { + Client { + endpoint: endpoint.into(), + headers: HashMap::new(), + reqwest_client: reqwest::Client::new(), + } + } + + /// Add a header to those sent with the requests. Can be used for things like authorization. + pub fn add_header(&mut self, name: &str, value: &str) { + self.headers.insert(name.into(), value.into()); + } + + /// Perform a query. + /// + // Lint disabled: We can pass by value because it's always an empty struct. + #[allow(clippy::needless_pass_by_value)] + pub async fn call( + &self, + _query: Q, + variables: Q::Variables, + ) -> Result, reqwest::Error> { + // TODO: remove the unwrap + // TODO: remove tests and test harness + // TODO: custom headers + let reqwest_response = self + .reqwest_client + .post(&self.endpoint) + .header("Content-Type", "application/json") + .body(serde_json::to_string(&Q::build_query(variables)).unwrap()) + .send() + .await?; + + let text_response = reqwest_response.text().await?; + + dbg!(&text_response); + + Ok(serde_json::from_str(&text_response).unwrap()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn client_new() { + Client::new("https://example.com/graphql"); + Client::new("/graphql"); + } +} diff --git a/graphql_client/src/lib.rs b/graphql_client/src/lib.rs index b0dca88dd..9f4b41523 100644 --- a/graphql_client/src/lib.rs +++ b/graphql_client/src/lib.rs @@ -14,13 +14,13 @@ pub use graphql_query_derive::*; use serde::*; -#[cfg(feature = "web")] -pub mod web; +#[cfg(feature = "client")] +pub mod client; use std::collections::HashMap; use std::fmt::{self, Display}; -doc_comment::doctest!("../../README.md"); +//doc_comment::doctest!("../../README.md"); /// A convenience trait that can be used to build a GraphQL request body. /// diff --git a/graphql_client/src/web.rs b/graphql_client/src/web.rs deleted file mode 100644 index 8f4b6031b..000000000 --- a/graphql_client/src/web.rs +++ /dev/null @@ -1,155 +0,0 @@ -//! Use graphql_client inside browsers with -//! [wasm-bindgen](https://github.com/rustwasm/wasm-bindgen). - -use crate::*; -use futures::{Future, IntoFuture}; -use log::*; -use std::collections::HashMap; -use thiserror::*; -use wasm_bindgen::{JsCast, JsValue}; -use wasm_bindgen_futures::JsFuture; - -/// The main interface to the library. -/// -/// The workflow is the following: -/// -/// - create a client -/// - (optionally) configure it -/// - use it to perform queries with the [call] method -pub struct Client { - endpoint: String, - headers: HashMap, -} - -/// All the ways a request can go wrong. -/// -/// not exhaustive -#[derive(Debug, Error, PartialEq)] -pub enum ClientError { - /// The body couldn't be built - #[error("Request body is not a valid string")] - Body, - /// An error caused by window.fetch - #[error("Network error")] - Network(String), - /// Error in a dynamic JS cast that should have worked - #[error("JS casting error")] - Cast, - /// No window object could be retrieved - #[error( - "No Window object available - the client works only in a browser (non-worker) context" - )] - NoWindow, - /// Response shape does not match the generated code - #[error("Response shape error")] - ResponseShape, - /// Response could not be converted to text - #[error("Response conversion to text failed (Response.text threw)")] - ResponseText, - /// Exception thrown when building the request - #[error("Error building the request")] - RequestError, - /// Other JS exception - #[error("Unexpected JS exception")] - JsException, -} - -impl Client { - /// Initialize a client. The `endpoint` parameter is the URI of the GraphQL API. - pub fn new(endpoint: Endpoint) -> Client - where - Endpoint: Into, - { - Client { - endpoint: endpoint.into(), - headers: HashMap::new(), - } - } - - /// Add a header to those sent with the requests. Can be used for things like authorization. - pub fn add_header(&mut self, name: &str, value: &str) { - self.headers.insert(name.into(), value.into()); - } - - /// Perform a query. - /// - // Lint disabled: We can pass by value because it's always an empty struct. - #[allow(clippy::needless_pass_by_value)] - pub fn call( - &self, - _query: Q, - variables: Q::Variables, - ) -> impl Future, Error = ClientError> + 'static { - // this can be removed when we convert to async/await - let endpoint = self.endpoint.clone(); - let custom_headers = self.headers.clone(); - - web_sys::window() - .ok_or_else(|| ClientError::NoWindow) - .into_future() - .and_then(move |window| { - serde_json::to_string(&Q::build_query(variables)) - .map_err(|_| ClientError::Body) - .map(move |body| (window, body)) - }) - .and_then(move |(window, body)| { - let mut request_init = web_sys::RequestInit::new(); - request_init - .method("POST") - .body(Some(&JsValue::from_str(&body))); - - web_sys::Request::new_with_str_and_init(&endpoint, &request_init) - .map_err(|_| ClientError::JsException) - .map(|request| (window, request)) - // "Request constructor threw"); - }) - .and_then(move |(window, request)| { - let headers = request.headers(); - headers - .set("Content-Type", "application/json") - .map_err(|_| ClientError::RequestError)?; - headers - .set("Accept", "application/json") - .map_err(|_| ClientError::RequestError)?; - - for (header_name, header_value) in custom_headers.iter() { - headers - .set(header_name, header_value) - .map_err(|_| ClientError::RequestError)?; - } - - Ok((window, request)) - }) - .and_then(move |(window, request)| { - JsFuture::from(window.fetch_with_request(&request)) - .map_err(|err| ClientError::Network(js_sys::Error::from(err).message().into())) - }) - .and_then(move |res| { - debug!("response: {:?}", res); - res.dyn_into::() - .map_err(|_| ClientError::Cast) - }) - .and_then(move |cast_response| { - cast_response.text().map_err(|_| ClientError::ResponseText) - }) - .and_then(move |text_promise| { - JsFuture::from(text_promise).map_err(|_| ClientError::ResponseText) - }) - .and_then(|text| { - let response_text = text.as_string().unwrap_or_default(); - debug!("response text as string: {:?}", response_text); - serde_json::from_str(&response_text).map_err(|_| ClientError::ResponseShape) - }) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn client_new() { - Client::new("https://example.com/graphql"); - Client::new("/graphql"); - } -} diff --git a/graphql_client/tests/client.rs b/graphql_client/tests/client.rs new file mode 100644 index 000000000..e966a83ce --- /dev/null +++ b/graphql_client/tests/client.rs @@ -0,0 +1,93 @@ +// use futures::Future; +use graphql_client::{client::Client, GraphQLQuery}; +// use wasm_bindgen::JsValue; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_test::wasm_bindgen_test_configure; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_test::*; + +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test_configure!(run_in_browser); + +#[cfg_attr(not(target_arch = "wasm32"), test)] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +fn build_client() { + // just to test it doesn't crash + Client::new("https://example.com/graphql"); + Client::new("/graphql"); +} + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "tests/countries_schema.graphql", + query_path = "tests/Germany.graphql" +)] +struct Germany; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(not(target_arch = "wasm32"), tokio::test)] +async fn test_germany() { + let response = Client::new("https://countries.trevorblades.com/") + .call(Germany, germany::Variables) + .await + .unwrap(); + let continent_name = response + .data + .expect("response data is not null") + .country + .expect("country is not null") + .continent + .name; + + assert_eq!(continent_name, "Europe"); +} + +#[derive(GraphQLQuery)] +#[graphql( + schema_path = "tests/countries_schema.graphql", + query_path = "tests/Germany.graphql" +)] +struct Country; + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(not(target_arch = "wasm32"), tokio::test)] +async fn test_country() { + let response = Client::new("https://countries.trevorblades.com/") + .call( + Country, + country::Variables { + country_code: "CN".to_owned(), + }, + ) + .await + .unwrap(); + let continent_name = response + .data + .expect("response data is not null") + .country + .expect("country is not null") + .continent + .name; + + assert_eq!(continent_name, "Asia"); +} + +#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] +#[cfg_attr(not(target_arch = "wasm32"), tokio::test)] +async fn test_bad_url() { + let response = Client::new("https://example.com/non-existent/graphql/endpoint") + .call( + Country, + country::Variables { + country_code: "CN".to_owned(), + }, + ) + .await; + + match response { + Ok(_) => panic!("The API endpoint does not exist, this should not be called."), + Err(e) => { + assert!(e.is_request()); + } + } +} diff --git a/graphql_client/tests/countries_schema.graphql b/graphql_client/tests/countries_schema.graphql new file mode 100644 index 000000000..1e83ca838 --- /dev/null +++ b/graphql_client/tests/countries_schema.graphql @@ -0,0 +1,77 @@ +directive @cacheControl( + maxAge: Int + scope: CacheControlScope +) on FIELD_DEFINITION | OBJECT | INTERFACE +enum CacheControlScope { + PUBLIC + PRIVATE +} + +type Continent { + code: ID! + name: String! + countries: [Country!]! +} + +input ContinentFilterInput { + code: StringQueryOperatorInput +} + +type Country { + code: ID! + name: String! + native: String! + phone: String! + continent: Continent! + capital: String + currency: String + languages: [Language!]! + emoji: String! + emojiU: String! + states: [State!]! +} + +input CountryFilterInput { + code: StringQueryOperatorInput + currency: StringQueryOperatorInput + continent: StringQueryOperatorInput +} + +type Language { + code: ID! + name: String + native: String + rtl: Boolean! +} + +input LanguageFilterInput { + code: StringQueryOperatorInput +} + +type Query { + continents(filter: ContinentFilterInput): [Continent!]! + continent(code: ID!): Continent + countries(filter: CountryFilterInput): [Country!]! + country(code: ID!): Country + languages(filter: LanguageFilterInput): [Language!]! + language(code: ID!): Language +} + +type State { + code: String + name: String! + country: Country! +} + +input StringQueryOperatorInput { + eq: String + ne: String + in: [String] + nin: [String] + regex: String + glob: String +} + +# The `Upload` scalar type represents a file upload. +scalar Upload + diff --git a/graphql_client/tests/web.rs b/graphql_client/tests/web.rs deleted file mode 100644 index 5a13b4340..000000000 --- a/graphql_client/tests/web.rs +++ /dev/null @@ -1,100 +0,0 @@ -#![cfg(target_arch = "wasm32")] - -use futures::Future; -use graphql_client::{web::Client, GraphQLQuery}; -use wasm_bindgen::JsValue; -use wasm_bindgen_test::wasm_bindgen_test_configure; -use wasm_bindgen_test::*; - -wasm_bindgen_test_configure!(run_in_browser); - -#[wasm_bindgen_test] -fn build_client() { - // just to test it doesn't crash - Client::new("https://example.com/graphql"); - Client::new("/graphql"); -} - -#[derive(GraphQLQuery)] -#[graphql( - schema_path = "tests/countries_schema.json", - query_path = "tests/Germany.graphql" -)] -struct Germany; - -#[wasm_bindgen_test(async)] -fn test_germany() -> impl Future { - Client::new("https://countries.trevorblades.com/") - .call(Germany, germany::Variables) - .map(|response| { - let continent_name = response - .data - .expect("response data is not null") - .country - .expect("country is not null") - .continent - .expect("continent is not null") - .name - .expect("germany is on a continent"); - - assert_eq!(continent_name, "Europe"); - }) - .map_err(|err| { - panic!("{:?}", err); - }) -} - -#[derive(GraphQLQuery)] -#[graphql( - schema_path = "tests/countries_schema.json", - query_path = "tests/Germany.graphql" -)] -struct Country; - -#[wasm_bindgen_test(async)] -fn test_country() -> impl Future { - Client::new("https://countries.trevorblades.com/") - .call( - Country, - country::Variables { - country_code: "CN".to_owned(), - }, - ) - .map(|response| { - let continent_name = response - .data - .expect("response data is not null") - .country - .expect("country is not null") - .continent - .expect("continent is not null") - .name - .expect("country is on a continent"); - - assert_eq!(continent_name, "Asia"); - }) - .map_err(|err| { - panic!("{:?}", err); - }) -} - -#[wasm_bindgen_test(async)] -fn test_bad_url() -> impl Future { - Client::new("https://example.com/non-existent/graphql/endpoint") - .call( - Country, - country::Variables { - country_code: "CN".to_owned(), - }, - ) - .map(|_response| panic!("The API endpoint does not exist, this should not be called.")) - .map_err(|err| { - assert_eq!( - err, - graphql_client::web::ClientError::Network( - "NetworkError when attempting to fetch resource.".into() - ) - ); - }) - .then(|_| Ok(())) -} From ca0e5196ec17beea269f7e2b7ff17eb044f14b82 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 30 Jul 2020 21:51:24 +0200 Subject: [PATCH 2/7] Fixed compilation errors and made tests pass * Moved tokio (for async tests) to only be used when not targeting wasm. * Fixed queries for tests to be up to date (ID! instead of String!) * Fixed example --- examples/web/Cargo.toml | 38 ++++++++++++++-------------- examples/web/examples/web.rs | 18 ++++++++----- graphql_client/Cargo.toml | 4 ++- graphql_client/src/client.rs | 25 ++++++++++++++++-- graphql_client/tests/Germany.graphql | 2 +- graphql_client/tests/client.rs | 5 ++-- graphql_client_web/src/lib.rs | 4 +-- 7 files changed, 62 insertions(+), 34 deletions(-) diff --git a/examples/web/Cargo.toml b/examples/web/Cargo.toml index 42499c6f0..021e1eb64 100644 --- a/examples/web/Cargo.toml +++ b/examples/web/Cargo.toml @@ -1,36 +1,36 @@ [package] -name = "web" -version = "0.1.0" authors = ["Tom Houlé "] edition = "2018" +name = "web" +version = "0.1.0" # https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-overrides #[profile.release] #lto = "thin" [dev-dependencies] -graphql_client = { path = "../../graphql_client" } -graphql_client_web = { path = "../../graphql_client_web" } -wasm-bindgen = "^0.2" -serde = { version = "1.0.67", features = ["derive"] } +graphql_client = {path = "../../graphql_client"} +graphql_client_web = {path = "../../graphql_client_web"} +js-sys = "0.3.44" lazy_static = "1.0.1" -js-sys = "0.3.6" -futures = "0.1.25" -wasm-bindgen-futures = "0.3.6" +serde = {version = "1.0.67", features = ["derive"]} +wasm-bindgen = "^0.2" +wasm-bindgen-futures = "0.4.17" [dev-dependencies.web-sys] -version = "0.3.6" features = [ - "console", - "Document", - "Element", - "EventTarget", - "Node", - "HtmlBodyElement", - "HtmlDocument", - "HtmlElement", + "console", + "Document", + "Element", + "EventTarget", + "Node", + "HtmlBodyElement", + "HtmlDocument", + "HtmlElement", + 'MouseEvent', ] +version = "0.3.6" [[example]] -name = "web" crate-type = ["cdylib"] +name = "web" diff --git a/examples/web/examples/web.rs b/examples/web/examples/web.rs index 3937e5400..405278973 100644 --- a/examples/web/examples/web.rs +++ b/examples/web/examples/web.rs @@ -1,4 +1,3 @@ -use futures::Future; use graphql_client::GraphQLQuery; use lazy_static::*; use std::cell::RefCell; @@ -6,6 +5,7 @@ use std::sync::Mutex; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use wasm_bindgen_futures::future_to_promise; +use wasm_bindgen_futures::{spawn_local, JsFuture}; #[derive(GraphQLQuery)] #[graphql( @@ -23,15 +23,15 @@ lazy_static! { static ref LAST_ENTRY: Mutex>> = Mutex::new(RefCell::new(None)); } -fn load_more() -> impl Future { - let client = graphql_client::web::Client::new("https://www.graphqlhub.com/graphql"); +async fn load_more() -> Result { + let client = graphql_client::client::Client::new("https://www.graphqlhub.com/graphql"); let variables = puppy_smiles::Variables { after: LAST_ENTRY .lock() .ok() .and_then(|opt| opt.borrow().to_owned()), }; - let response = client.call(PuppySmiles, variables); + let response = client.call(PuppySmiles, variables).await; response .map(|response| { @@ -59,9 +59,13 @@ fn add_load_more_button() { .create_element("button") .expect_throw("could not create button"); btn.set_inner_html("I WANT MORE PUPPIES"); - let on_click = Closure::wrap( - Box::new(move || future_to_promise(load_more())) as Box js_sys::Promise> - ); + + let on_click = Closure::wrap(Box::new(move |_event: web_sys::MouseEvent| { + spawn_local(async { + load_more().await; + }); + }) as Box); + btn.add_event_listener_with_callback( "click", &on_click diff --git a/graphql_client/Cargo.toml b/graphql_client/Cargo.toml index 2f088edd2..d5199445d 100644 --- a/graphql_client/Cargo.toml +++ b/graphql_client/Cargo.toml @@ -50,10 +50,12 @@ optional = true version = "^0.4" [dev-dependencies] -tokio = {version = "^0.2", features = ["rt-threaded", "macros"]} # Note: If we bumpup wasm-bindge-test version, we should change CI setting. wasm-bindgen-test = "^0.3" +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +tokio = {version = "^0.2", features = ["rt-threaded", "macros"]} + [features] client = ["reqwest"] default = ["client"] diff --git a/graphql_client/src/client.rs b/graphql_client/src/client.rs index b6d88bfb0..967b03672 100644 --- a/graphql_client/src/client.rs +++ b/graphql_client/src/client.rs @@ -42,7 +42,7 @@ impl Client { &self, _query: Q, variables: Q::Variables, - ) -> Result, reqwest::Error> { + ) -> Result, ClientError> { // TODO: remove the unwrap // TODO: remove tests and test harness // TODO: custom headers @@ -58,7 +58,28 @@ impl Client { dbg!(&text_response); - Ok(serde_json::from_str(&text_response).unwrap()) + Ok(serde_json::from_str(&text_response)?) + } +} + +/// TODO +#[derive(Debug)] +pub enum ClientError { + /// TODO + ReqwestError(reqwest::Error), + /// TODO + SerdeError(serde_json::Error), +} + +impl From for ClientError { + fn from(e: reqwest::Error) -> Self { + ClientError::ReqwestError(e) + } +} + +impl From for ClientError { + fn from(e: serde_json::Error) -> Self { + ClientError::SerdeError(e) } } diff --git a/graphql_client/tests/Germany.graphql b/graphql_client/tests/Germany.graphql index 322d4f391..d1321dddd 100644 --- a/graphql_client/tests/Germany.graphql +++ b/graphql_client/tests/Germany.graphql @@ -7,7 +7,7 @@ query Germany { } } -query Country($countryCode: String!) { +query Country($countryCode: ID!) { country(code: $countryCode) { name continent { diff --git a/graphql_client/tests/client.rs b/graphql_client/tests/client.rs index e966a83ce..b863eb0ad 100644 --- a/graphql_client/tests/client.rs +++ b/graphql_client/tests/client.rs @@ -86,8 +86,9 @@ async fn test_bad_url() { match response { Ok(_) => panic!("The API endpoint does not exist, this should not be called."), - Err(e) => { - assert!(e.is_request()); + Err(_e) => { + // TODO: What to assert here? + // That url gives a response but it's not json, but in WASM it's blocked by cors } } } diff --git a/graphql_client_web/src/lib.rs b/graphql_client_web/src/lib.rs index 02a066d73..14230ba49 100644 --- a/graphql_client_web/src/lib.rs +++ b/graphql_client_web/src/lib.rs @@ -1,6 +1,6 @@ #![deprecated( - note = "graphql_client_web is deprecated. The web client is now part of the graphql_client crate, with the \"web\" feature." + note = "graphql_client_web is deprecated. The web client is now part of the graphql_client crate, with the default \"client\" feature." )] -pub use graphql_client::web::*; +pub use graphql_client::client::*; pub use graphql_client::{self, *}; From b64bd63c61f34eadb7e5de247d11416a7f13ccda Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 30 Jul 2020 21:57:01 +0200 Subject: [PATCH 3/7] Fixed formatting with prettier --- graphql_client/tests/countries_schema.graphql | 1 - 1 file changed, 1 deletion(-) diff --git a/graphql_client/tests/countries_schema.graphql b/graphql_client/tests/countries_schema.graphql index 1e83ca838..327e75698 100644 --- a/graphql_client/tests/countries_schema.graphql +++ b/graphql_client/tests/countries_schema.graphql @@ -74,4 +74,3 @@ input StringQueryOperatorInput { # The `Upload` scalar type represents a file upload. scalar Upload - From 1b2cd75fd6820eb8c14a26df86a10280a6cc0c72 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 30 Jul 2020 21:59:52 +0200 Subject: [PATCH 4/7] Fixed clippy lints --- examples/web/examples/web.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/web/examples/web.rs b/examples/web/examples/web.rs index 405278973..e63e3659b 100644 --- a/examples/web/examples/web.rs +++ b/examples/web/examples/web.rs @@ -4,8 +4,7 @@ use std::cell::RefCell; use std::sync::Mutex; use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; -use wasm_bindgen_futures::future_to_promise; -use wasm_bindgen_futures::{spawn_local, JsFuture}; +use wasm_bindgen_futures::spawn_local; #[derive(GraphQLQuery)] #[graphql( @@ -62,7 +61,7 @@ fn add_load_more_button() { let on_click = Closure::wrap(Box::new(move |_event: web_sys::MouseEvent| { spawn_local(async { - load_more().await; + load_more().await.unwrap(); }); }) as Box); From c5b46c86575951da4702fc5a551d1807b5572d19 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Fri, 31 Jul 2020 18:14:04 +0200 Subject: [PATCH 5/7] Fix clippy warning --- graphql_client_codegen/src/generated_module.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphql_client_codegen/src/generated_module.rs b/graphql_client_codegen/src/generated_module.rs index c73a39ea3..a2970a00e 100644 --- a/graphql_client_codegen/src/generated_module.rs +++ b/graphql_client_codegen/src/generated_module.rs @@ -67,7 +67,7 @@ impl<'a> GeneratedModule<'a> { const __QUERY_WORKAROUND: &str = include_str!(#path); ) }) - .unwrap_or_else(|| quote! {}); + .unwrap_or_else(proc_macro2::TokenStream::new); let query_string = &self.query_string; let impls = self.build_impls()?; From 208dbd75df2ac79366879d84022e20cc70f780d4 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Fri, 31 Jul 2020 18:29:28 +0200 Subject: [PATCH 6/7] Renamed module from 'client' to 'web' --- examples/web/examples/web.rs | 2 +- graphql_client/Cargo.toml | 6 +++--- graphql_client/src/{client.rs => http.rs} | 0 graphql_client/src/lib.rs | 4 ++-- graphql_client/tests/client.rs | 2 +- graphql_client_web/src/lib.rs | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) rename graphql_client/src/{client.rs => http.rs} (100%) diff --git a/examples/web/examples/web.rs b/examples/web/examples/web.rs index e63e3659b..f144fb359 100644 --- a/examples/web/examples/web.rs +++ b/examples/web/examples/web.rs @@ -23,7 +23,7 @@ lazy_static! { } async fn load_more() -> Result { - let client = graphql_client::client::Client::new("https://www.graphqlhub.com/graphql"); + let client = graphql_client::http::Client::new("https://www.graphqlhub.com/graphql"); let variables = puppy_smiles::Variables { after: LAST_ENTRY .lock() diff --git a/graphql_client/Cargo.toml b/graphql_client/Cargo.toml index d5199445d..07b3659fe 100644 --- a/graphql_client/Cargo.toml +++ b/graphql_client/Cargo.toml @@ -57,6 +57,6 @@ wasm-bindgen-test = "^0.3" tokio = {version = "^0.2", features = ["rt-threaded", "macros"]} [features] -client = ["reqwest"] -default = ["client"] -web = [] +default = ["http"] +http = ["reqwest"] +web = ["http"] diff --git a/graphql_client/src/client.rs b/graphql_client/src/http.rs similarity index 100% rename from graphql_client/src/client.rs rename to graphql_client/src/http.rs diff --git a/graphql_client/src/lib.rs b/graphql_client/src/lib.rs index 9f4b41523..cb295f757 100644 --- a/graphql_client/src/lib.rs +++ b/graphql_client/src/lib.rs @@ -14,8 +14,8 @@ pub use graphql_query_derive::*; use serde::*; -#[cfg(feature = "client")] -pub mod client; +#[cfg(feature = "http")] +pub mod http; use std::collections::HashMap; use std::fmt::{self, Display}; diff --git a/graphql_client/tests/client.rs b/graphql_client/tests/client.rs index b863eb0ad..d52351cbb 100644 --- a/graphql_client/tests/client.rs +++ b/graphql_client/tests/client.rs @@ -1,5 +1,5 @@ // use futures::Future; -use graphql_client::{client::Client, GraphQLQuery}; +use graphql_client::{http::Client, GraphQLQuery}; // use wasm_bindgen::JsValue; #[cfg(target_arch = "wasm32")] use wasm_bindgen_test::wasm_bindgen_test_configure; diff --git a/graphql_client_web/src/lib.rs b/graphql_client_web/src/lib.rs index 14230ba49..8dfcce8da 100644 --- a/graphql_client_web/src/lib.rs +++ b/graphql_client_web/src/lib.rs @@ -2,5 +2,5 @@ note = "graphql_client_web is deprecated. The web client is now part of the graphql_client crate, with the default \"client\" feature." )] -pub use graphql_client::client::*; +pub use graphql_client::http::*; pub use graphql_client::{self, *}; From ae12bdb0d6971300a9cb8cf524141488d1efe9d2 Mon Sep 17 00:00:00 2001 From: Midas Lambrichts Date: Thu, 1 Oct 2020 21:46:02 +0200 Subject: [PATCH 7/7] Removed some excessive left-over code After PR review, removed some excessive leftover comment and debug statement. --- graphql_client/src/http.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/graphql_client/src/http.rs b/graphql_client/src/http.rs index 967b03672..e43737bbb 100644 --- a/graphql_client/src/http.rs +++ b/graphql_client/src/http.rs @@ -43,7 +43,6 @@ impl Client { _query: Q, variables: Q::Variables, ) -> Result, ClientError> { - // TODO: remove the unwrap // TODO: remove tests and test harness // TODO: custom headers let reqwest_response = self @@ -56,8 +55,6 @@ impl Client { let text_response = reqwest_response.text().await?; - dbg!(&text_response); - Ok(serde_json::from_str(&text_response)?) } }