Skip to content

Commit

Permalink
feat(fetcher): remove Option on follow and accept second argument…
Browse files Browse the repository at this point in the history
… for `fetch!` macro
  • Loading branch information
Vexcited committed Dec 31, 2024
1 parent 1509e7d commit c4dab7a
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 24 deletions.
6 changes: 3 additions & 3 deletions fetcher-macros/examples/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use fetcher::{fetch, Request};
use fetcher::{fetch, Request, Method};

#[tokio::main]
async fn main () {
let request = Request {
url: "https://example.com".parse().unwrap(),
method: fetcher::Method::GET,
method: Method::GET,
headers: Default::default(),
body: None,
follow: None,
follow: false,
};

let response = fetch!(request);
Expand Down
60 changes: 50 additions & 10 deletions fetcher-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,63 @@
extern crate proc_macro;

use syn::{parse_macro_input, Expr};
use syn::{parse_macro_input, Expr, punctuated::Punctuated, Token};
use proc_macro::TokenStream;
use quote::quote;

///
/// ## Examples
///
/// ```rust
/// // will use the variable `fetcher` on wasm32 target
/// #[cfg_attr(target_arch = "wasm32", wasm::append_fetcher)]
/// async fn something () {
/// let response = fetch!(request);
/// }
///
/// async fn something (session: &Session) {
/// // will use the `session.fetcher()` method on wasm32 target
/// // return type of `session.fetcher()` is `&js_sys::Function`
/// let response = fetch!(request, session.fetcher());
/// }
/// ```
#[proc_macro]
pub fn fetch(input: TokenStream) -> TokenStream {
let request: Expr = parse_macro_input!(input as Expr);
let args = parse_macro_input!(input with Punctuated::<Expr, Token![,]>::parse_terminated);

let expanded = quote! {
{
#[cfg(target_arch = "wasm32")]
let response = fetcher::fetch(#request, fetcher).await;
#[cfg(not(target_arch = "wasm32"))]
let response = fetcher::fetch(#request).await;
let expanded = match args.len() {
1 => { // here we expect #[wasm::append_fetcher] to be used so `fetcher` is defined.
let req = &args[0];
quote! {
{
#[cfg(target_arch = "wasm32")]
let response = fetcher::fetch(#req, &fetcher).await;
#[cfg(not(target_arch = "wasm32"))]
let response = fetcher::fetch(#req).await;

response
response
}
}
},
2 => { // here we expect the fetcher to come from another source (manual)
let req = &args[0];
let fetcher_expr = &args[1];
quote! {
{
#[cfg(target_arch = "wasm32")]
let response = fetcher::fetch(#req, #fetcher_expr).await;
#[cfg(not(target_arch = "wasm32"))]
let response = fetcher::fetch(#req).await;

response
}
}
},
_ => {
quote! {
compile_error!("fetch! macro supports at most two arguments: fetch!(request) or fetch!(request, fetcher_expr)");
}
}
};

TokenStream::from(expanded)
expanded.into()
}
19 changes: 9 additions & 10 deletions fetcher/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ pub use url::Url;

#[cfg(not(target_arch = "wasm32"))]
pub async fn fetch (request: Request) -> Response {
use reqwest::Client;
use reqwest::{Client, redirect::Policy};

let client = if request.follow == Some(false) {
let client = if !request.follow {
Client::builder()
.redirect(reqwest::redirect::Policy::none())
.redirect(Policy::none())
.build().unwrap()
} else {
}
else {
Client::new()
};

Expand Down Expand Up @@ -42,7 +43,7 @@ pub async fn fetch (request: Request) -> Response {
}

#[cfg(target_arch = "wasm32")]
pub async fn fetch (request: Request, fetcher: js_sys::Function) -> Response {
pub async fn fetch (request: Request, fetcher: &js_sys::Function) -> Response {
use wasm_bindgen_futures::JsFuture;
use wasm_bindgen::JsValue;
use js_sys::Promise;
Expand All @@ -59,14 +60,14 @@ pub struct Request {
pub body: Option<String>,
pub headers: HeaderMap,
/// Whether we should follow redirects or not.
pub follow: Option<bool>,
pub follow: bool,
}

impl Serialize for Request {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
use serde::ser::SerializeStruct;

let mut state = serializer.serialize_struct("Request", 3)?;
let mut state = serializer.serialize_struct("Request", 4)?;
state.serialize_field("url", &self.url.as_str())?;
state.serialize_field("method", &self.method.as_str())?;

Expand All @@ -80,9 +81,7 @@ impl Serialize for Request {
state.serialize_field("body", body)?;
}

if let Some(follow) = self.follow {
state.serialize_field("follow", &follow)?;
}
state.serialize_field("follow", &self.follow)?;

state.end()
}
Expand Down
10 changes: 9 additions & 1 deletion wasm/examples/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,17 @@ pub fn update() {
pub struct Session {
instance_url: String,
php_sess_id: String,
fetcher: js_sys::Function,
}

#[wasm::export]
impl Session {
#[wasm_bindgen(constructor)]
pub fn new(instance_url: String, php_sess_id: String) -> Self {
pub fn new(instance_url: String, php_sess_id: String, fetcher: js_sys::Function) -> Self {
Self {
instance_url,
php_sess_id,
fetcher,
}
}

Expand All @@ -35,6 +37,12 @@ impl Session {
}
}

impl Session {
pub fn fetcher (&self) -> &js_sys::Function {
&self.fetcher
}
}

fn main() {
println!("Hello, world!");
}

0 comments on commit c4dab7a

Please sign in to comment.