diff --git a/examples/loop_yield_data_state.rs b/examples/loop_yield_data_state.rs index faca294..d424d48 100644 --- a/examples/loop_yield_data_state.rs +++ b/examples/loop_yield_data_state.rs @@ -2,8 +2,8 @@ // the same. This example demonstrates how this crate can be used with the DataState type. use anyhow::Context; -use reqwest::{Method, RequestBuilder, StatusCode}; -use reqwest_cross::{fetch, reqwest, Awaiting, DataState}; +use reqwest::Method; +use reqwest_cross::{fetch_plus, reqwest, Awaiting, DataState}; #[cfg(all(not(target_arch = "wasm32"), feature = "native-tokio"))] #[tokio::main] @@ -37,9 +37,14 @@ async fn common_code() -> Result<(), Box> { } else { state.get(|| { let req = client.request(Method::GET, "http://httpbin.org/get"); - Awaiting(send_request_give_back_status(req, || { + let response_handler = |resp: reqwest::Result| async { + resp.map(|resp| resp.status()) + .context("Request failed, got an error back") + }; + let ui_notify = || { println!("Request Completed, this is where you would wake up your UI thread"); - })) + }; + Awaiting(fetch_plus(req, response_handler, ui_notify)) }); reqwest_cross::yield_now().await; } @@ -48,28 +53,7 @@ async fn common_code() -> Result<(), Box> { Ok(()) } -fn send_request_give_back_status( - req: RequestBuilder, - ui_notify: F, -) -> reqwest_cross::oneshot::Receiver> -where - F: FnOnce() + Send + 'static, -{ - let (tx, rx) = reqwest_cross::oneshot::channel(); - let on_done = move |resp: reqwest::Result| async { - let status_code = resp - .map(|resp| resp.status()) - .context("Request failed, got an error back"); - tx.send(status_code).expect("failed to send oneshot msg"); - ui_notify(); - }; - fetch(req, on_done); - println!("Request sent"); - rx -} - #[cfg(all(test, not(target_arch = "wasm32")))] - mod tests { #[tokio::test] diff --git a/src/lib.rs b/src/lib.rs index 2e92096..0d412d0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,7 @@ mod wrappers; mod yield_; pub use data_state::{Awaiting, DataState, DataStateError, ErrorBounds}; -pub use wrappers::fetch; +pub use wrappers::{fetch, fetch_plus}; #[cfg(feature = "yield_now")] pub use yield_::yield_now; diff --git a/src/wrappers.rs b/src/wrappers.rs index c239cc7..9edd923 100644 --- a/src/wrappers.rs +++ b/src/wrappers.rs @@ -1,6 +1,9 @@ //! Stores the wrapper functions that can be called from either native or wasm //! code +use std::{fmt::Debug, future::Future}; +use tracing::error; + #[cfg(not(target_arch = "wasm32"))] /// Performs a HTTP requests and calls the given callback when done. NB: Needs /// to use a callback to prevent blocking on the thread that initiates the @@ -76,3 +79,28 @@ where { crate::wasm::spawn(future); } + +/// Wraps the call to fetch with the surrounding boilerplate +pub fn fetch_plus( + req: reqwest::RequestBuilder, + response_handler: FResponseHandler, + ui_notify: FNotify, +) -> crate::oneshot::Receiver> +where + FResponseHandler: FnOnce(reqwest::Result) -> Fut + Send + 'static, + Fut: Future> + Send, + Ret: Send + 'static, + Fut::Output: Debug, + FNotify: FnOnce() + Send + 'static, +{ + let (tx, rx) = crate::oneshot::channel(); + let on_done = move |resp: reqwest::Result| async { + let output = response_handler(resp).await; + match tx.send(output) { + Ok(()) => ui_notify(), + Err(handler_output) => error!(?handler_output, "failed to send output from handler"), + }; + }; + fetch(req, on_done); + rx +}