Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional reqwest-middleware feature #1074

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ rand = "0.9.0"
regex = "1.11.1"
regress = "0.10.3"
reqwest = { version = "0.12.4", default-features = false, features = ["json", "stream"] }
reqwest-middleware = { version = "0.4.1", features = ["json"] }
rustfmt-wrapper = "0.2.1"
schemars = { version = "0.8.21", features = ["chrono", "uuid1"] }
semver = "1.0.25"
Expand Down
7 changes: 7 additions & 0 deletions cargo-progenitor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ categories = ["api-bindings", "development-tools::cargo-plugins"]

default-run = "cargo-progenitor"

[features]
middleware = [
"progenitor/middleware",
"progenitor-client/middleware",
"progenitor-impl/middleware",
]

[dependencies]
progenitor = { workspace = true, default-features = false }
progenitor-client = { workspace = true }
Expand Down
6 changes: 6 additions & 0 deletions cargo-progenitor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,8 @@ struct Dependencies {
rand: &'static str,
regress: &'static str,
reqwest: &'static str,
#[cfg(feature = "middleware")]
reqwest_middleware: &'static str,
serde: &'static str,
serde_json: &'static str,
serde_urlencoded: &'static str,
Expand All @@ -233,6 +235,8 @@ static DEPENDENCIES: Dependencies = Dependencies {
rand: "0.8",
regress: "0.10",
reqwest: "0.12",
#[cfg(feature = "middleware")]
reqwest_middleware: "0.4",
serde: "1.0",
serde_json: "1.0",
serde_urlencoded: "0.7",
Expand All @@ -244,6 +248,8 @@ pub fn dependencies(builder: Generator, include_client: bool) -> Vec<String> {
format!("bytes = \"{}\"", DEPENDENCIES.bytes),
format!("futures-core = \"{}\"", DEPENDENCIES.futures),
format!("reqwest = {{ version = \"{}\", default-features=false, features = [\"json\", \"stream\"] }}", DEPENDENCIES.reqwest),
#[cfg(feature = "middleware")]
format!("reqwest-middleware = {{ version = \"{}\", default-features=false, features = [\"json\"] }}", DEPENDENCIES.reqwest_middleware),
format!("serde = {{ version = \"{}\", features = [\"derive\"] }}", DEPENDENCIES.serde),
format!("serde_urlencoded = \"{}\"", DEPENDENCIES.serde_urlencoded),
];
Expand Down
4 changes: 4 additions & 0 deletions example-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ version = "0.0.1"
authors = ["Adam H. Leventhal <ahl@oxidecomputer.com>"]
edition = "2021"

[features]
middleware = ["dep:reqwest-middleware","progenitor-client/middleware"]

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
progenitor-client = { path = "../progenitor-client" }
reqwest = { version = "0.12.4", features = ["json", "stream"] }
reqwest-middleware = { version = "0.4.1", features = ["json"], optional = true }
base64 = "0.22"
rand = "0.9"
serde = { version = "1.0", features = ["derive"] }
Expand Down
4 changes: 4 additions & 0 deletions example-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ version = "0.0.1"
authors = ["Adam H. Leventhal <ahl@oxidecomputer.com>"]
edition = "2021"

[features]
middleware = ["dep:reqwest-middleware","progenitor/middleware"]

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
progenitor = { path = "../progenitor" }
reqwest = { version = "0.12.4", features = ["json", "stream"] }
reqwest-middleware = { version = "0.4.1", features = ["json"], optional = true }
schemars = { version = "0.8.21", features = ["uuid1"] }
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.14", features = ["serde", "v4"] }
4 changes: 4 additions & 0 deletions example-macro/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ async fn add_auth_headers(
Ok(())
}

#[cfg(not(feature = "middleware"))]
fn all_done(_result: &reqwest::Result<reqwest::Response>) {}

#[cfg(feature = "middleware")]
fn all_done(_result: &reqwest_middleware::Result<reqwest::Response>) {}

mod buildomat {
use progenitor::generate_api;

Expand Down
8 changes: 8 additions & 0 deletions example-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ name = "example-wasm"
version = "0.1.0"
edition = "2021"

[features]
middleware = [
"dep:reqwest-middleware",
"progenitor/middleware",
"progenitor-client/middleware",
]

[dependencies]
chrono = { version = "0.4", features = ["serde"] }
progenitor-client = { path = "../progenitor-client" }
reqwest = { version = "0.12.4", features = ["json", "stream"] }
reqwest-middleware = { version = "0.4.1", features = ["json"], optional = true }
base64 = "0.22"
serde = { version = "1.0", features = ["derive"] }
uuid = { version = "1.14", features = ["serde", "v4", "js"] }
Expand Down
5 changes: 5 additions & 0 deletions progenitor-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ license = "MPL-2.0"
repository = "https://github.com/oxidecomputer/progenitor.git"
description = "An OpenAPI client generator - client support"

[features]
middleware = ["dep:anyhow","dep:reqwest-middleware"]

[dependencies]
anyhow = { workspace = true, optional = true }
bytes = { workspace = true }
futures-core = { workspace = true }
percent-encoding = { workspace = true }
reqwest = { workspace = true }
reqwest-middleware = { workspace = true, optional = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_urlencoded = { workspace = true }
Expand Down
25 changes: 25 additions & 0 deletions progenitor-client/src/progenitor_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use std::ops::{Deref, DerefMut};

use bytes::Bytes;
use futures_core::Stream;
#[cfg(not(feature = "middleware"))]
use reqwest::RequestBuilder;
#[cfg(feature = "middleware")]
use reqwest_middleware::RequestBuilder;
use serde::{de::DeserializeOwned, ser::SerializeStruct, Serialize};

#[cfg(not(target_arch = "wasm32"))]
Expand Down Expand Up @@ -249,6 +252,10 @@ pub enum Error<E = ()> {

/// An error occurred in the processing of a request post-hook.
PostHookError(String),

#[cfg(feature = "middleware")]
/// An error occurred when processing middleware.
MiddlewareError(anyhow::Error),
}

impl<E> Error<E> {
Expand All @@ -264,6 +271,8 @@ impl<E> Error<E> {
Error::ResponseBodyError(e) => e.status(),
Error::InvalidResponsePayload(_, _) => None,
Error::UnexpectedResponse(r) => Some(r.status()),
#[cfg(feature = "middleware")]
Error::MiddlewareError(_) => None,
}
}

Expand All @@ -290,6 +299,8 @@ impl<E> Error<E> {
Error::ResponseBodyError(e) => Error::ResponseBodyError(e),
Error::InvalidResponsePayload(b, e) => Error::InvalidResponsePayload(b, e),
Error::UnexpectedResponse(r) => Error::UnexpectedResponse(r),
#[cfg(feature = "middleware")]
Error::MiddlewareError(e) => Error::MiddlewareError(e),
}
}
}
Expand All @@ -300,6 +311,16 @@ impl<E> From<reqwest::Error> for Error<E> {
}
}

#[cfg(feature = "middleware")]
impl<E> From<reqwest_middleware::Error> for Error<E> {
fn from(e: reqwest_middleware::Error) -> Self {
match e {
reqwest_middleware::Error::Middleware(e) => Self::MiddlewareError(e),
reqwest_middleware::Error::Reqwest(e) => Self::CommunicationError(e),
}
}
}

impl<E> From<reqwest::header::InvalidHeaderValue> for Error<E> {
fn from(e: reqwest::header::InvalidHeaderValue) -> Self {
Self::InvalidRequest(e.to_string())
Expand Down Expand Up @@ -340,6 +361,10 @@ where
Error::PostHookError(s) => {
write!(f, "Post-hook Error: {}", s)?;
}
#[cfg(feature = "middleware")]
Error::MiddlewareError(e) => {
write!(f, "Middleware Error: {}", e)?;
}
}

if f.alternate() {
Expand Down
4 changes: 4 additions & 0 deletions progenitor-impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ description = "An OpenAPI client generator - core implementation"
repository = "https://github.com/oxidecomputer/progenitor.git"
readme = "../README.md"

[features]
middleware = ["progenitor-client/middleware"]

[dependencies]
heck = { workspace = true }
http = { workspace = true }
Expand All @@ -31,6 +34,7 @@ http = { workspace = true }
hyper = { workspace = true }
progenitor-client = { workspace = true }
reqwest = { workspace = true }
reqwest-middleware = { workspace = true }
rustfmt-wrapper = { workspace = true }
semver = { workspace = true }
serde_yaml = { workspace = true }
Expand Down
33 changes: 25 additions & 8 deletions progenitor-impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,20 @@ impl Generator {
s
};

#[cfg(not(feature = "middleware"))]
let client_ty = quote! { reqwest::Client };

#[cfg(feature = "middleware")]
let client_ty = quote! { reqwest_middleware::ClientWithMiddleware };

#[cfg(not(feature = "middleware"))]
let build_middleware = quote! {};

#[cfg(feature = "middleware")]
let build_middleware = quote! {
let built_client = reqwest_middleware::ClientBuilder::new(built_client).build();
};

let version_str = &spec.info.version;

// The allow(unused_imports) on the `pub use` is necessary with Rust
Expand All @@ -428,15 +442,15 @@ impl Generator {
#[doc = #client_docstring]
pub struct Client {
pub(crate) baseurl: String,
pub(crate) client: reqwest::Client,
pub(crate) client: #client_ty,
#inner_property
}

impl Client {
/// Create a new client.
///
/// `baseurl` is the base URL provided to the internal
/// `reqwest::Client`, and should include a scheme and hostname,
/// HTTP client, and should include a scheme and hostname,
/// as well as port and a path stem if applicable.
pub fn new(
baseurl: &str,
Expand All @@ -453,18 +467,21 @@ impl Generator {
#[cfg(target_arch = "wasm32")]
let client = reqwest::ClientBuilder::new();

Self::new_with_client(baseurl, client.build().unwrap(), #inner_value)
let built_client = client.build().unwrap();
#build_middleware

Self::new_with_client(baseurl, built_client, #inner_value)
}

/// Construct a new client with an existing `reqwest::Client`,
/// Construct a new client with an existing HTTP client
/// allowing more control over its configuration.
///
/// `baseurl` is the base URL provided to the internal
/// `reqwest::Client`, and should include a scheme and hostname,
/// HTTP client, and should include a scheme and hostname,
/// as well as port and a path stem if applicable.
pub fn new_with_client(
baseurl: &str,
client: reqwest::Client,
client: #client_ty,
#inner_parameter
) -> Self {
Self {
Expand All @@ -479,8 +496,8 @@ impl Generator {
&self.baseurl
}

/// Get the internal `reqwest::Client` used to make requests.
pub fn client(&self) -> &reqwest::Client {
/// Get the internal HTTP client used to make requests.
pub fn client(&self) -> &#client_ty {
&self.client
}

Expand Down
Loading