Upgrade axum.

Breaks docs.

Signed-off-by: Omar Zabala-Ferrera <73452461+ozabalaferrera@users.noreply.github.com>
This commit is contained in:
Omar Zabala-Ferrera 2024-07-13 23:40:55 -04:00
parent bf45f01602
commit 03021f7242
No known key found for this signature in database
11 changed files with 121 additions and 43 deletions

View File

@ -27,7 +27,7 @@ actix = ["actix-web", "actix-http", "async-trait", "bytes", "futures", "http"]
reqwest = ["reqwest-lib", "async-trait", "bytes", "http", "uuid/js"]
rdkafka = ["rdkafka-lib", "bytes", "futures"]
warp = ["warp-lib", "bytes", "http", "hyper"]
axum = ["bytes", "http", "hyper", "axum-lib", "http-body", "async-trait"]
axum = ["bytes", "http-1-1", "hyper-1-3", "axum-lib-0-7", "http-body-1-0", "http-body-util", "async-trait"]
poem = ["bytes", "http", "poem-lib", "hyper", "async-trait"]
nats = ["nats-lib"]
@ -50,10 +50,15 @@ rdkafka-lib = { version = "^0.36", features = ["cmake-build"], optional = true,
warp-lib = { version = "^0.3", optional = true, package = "warp" }
async-trait = { version = "^0.1.33", optional = true }
bytes = { version = "^1.0", optional = true }
# bytes-1-6 = { version = "^1.6", optional = true, package="bytes" }
futures = { version = "^0.3", optional = true }
http = { version = "0.2", optional = true }
http-1-1 = { version = "1.1", optional = true, package = "http"}
axum-lib = { version = "^0.6", optional = true, package="axum"}
axum-lib-0-7 = { version = "^0.7", optional = true, package="axum"}
http-body = { version = "^0.4", optional = true }
http-body-1-0 = { version = "^1.0", optional = true, package="http-body" }
http-body-util = {version = "^0.1", optional = true}
poem-lib = { version = "=1.2.34", optional = true, package = "poem" }
nats-lib = { version = "0.21.0", optional = true, package = "nats" }
@ -65,6 +70,7 @@ web-sys = { version = "^0.3", features = ["Window", "Location"] }
[target.'cfg(not(target_os = "wasi"))'.dependencies]
hyper = { version = "^0.14", optional = true }
hyper-1-3 = { version = "^1.3", optional = true, package="hyper" }
[target.'cfg(all(target_arch = "wasm32", target_os = "wasi"))'.dependencies]
hyper_wasi = { version = "0.15", features = ["full"], optional = true }

View File

@ -1,45 +1,52 @@
use axum_lib as axum;
use async_trait::async_trait;
use axum::extract::FromRequest;
use axum::http::Request;
use http::request::Parts;
use axum::body::Bytes;
use axum::extract::{FromRequest, Request};
use axum::response::Response;
use axum_lib_0_7 as axum;
use http::StatusCode;
use http_body::Body;
use hyper::body;
use http_1_1 as http;
use crate::binding::http::to_event;
use crate::event::Event;
type BoxError = Box<dyn std::error::Error + Send + Sync>;
#[async_trait]
impl<S, B> FromRequest<S, B> for Event
impl<S> FromRequest<S> for Event
where
B: Body + Send + 'static,
B::Data: Send,
B::Error: Into<BoxError>,
Bytes: FromRequest<S>,
S: Send + Sync,
{
type Rejection = (StatusCode, String);
type Rejection = Response;
async fn from_request(req: Request<B>, _state: &S) -> Result<Self, Self::Rejection> {
let (Parts { headers, .. }, req_body) = req.into_parts();
let buf = body::to_bytes(req_body)
.await
.map_err(|e| (StatusCode::BAD_REQUEST, format!("{}", e.into())))?
.to_vec();
async fn from_request(
req: Request,
_state: &S,
) -> Result<Self, Self::Rejection> {
let (parts, body) = req.into_parts();
to_event(&headers, buf).map_err(|e| (StatusCode::BAD_REQUEST, format!("{}", e)))
let body =
axum::body::to_bytes(body, usize::MAX).await.map_err(|e| {
Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(axum::body::Body::from(e.to_string()))
.unwrap()
})?;
to_event(&parts.headers, body.to_vec()).map_err(|e| {
Response::builder()
.status(StatusCode::BAD_REQUEST)
.body(axum::body::Body::from(e.to_string()))
.unwrap()
})
}
}
#[cfg(test)]
mod tests {
use axum_lib as axum;
use axum_lib_0_7 as axum;
use super::*;
use axum::body::Body;
use axum::extract::FromRequest;
use axum::http::{self, Request, StatusCode};
use crate::test::fixtures;
@ -80,7 +87,7 @@ mod tests {
assert!(result.is_err());
let rejection = result.unwrap_err();
let reason = rejection.0;
let reason = rejection.status();
assert_eq!(reason, StatusCode::BAD_REQUEST)
}

View File

@ -6,13 +6,14 @@
//! To echo events:
//!
//! ```
//! use axum_lib as axum;
//! # use axum_lib_0_7 as axum;
//! use axum::{
//! routing::{get, post},
//! Router,
//! };
//! use cloudevents::Event;
//! use http::StatusCode;
//! # use http_1_1 as http;
//!
//! fn app() -> Router {
//! Router::new()
@ -31,13 +32,14 @@
//! To create event inside request handlers and send them as responses:
//!
//! ```
//! use axum_lib as axum;
//! # use axum_lib_0_7 as axum;
//! use axum::{
//! routing::{get, post},
//! Router,
//! };
//! use cloudevents::{Event, EventBuilder, EventBuilderV10};
//! use http::StatusCode;
//! # use http_1_1 as http;
//! use serde_json::json;
//!
//! fn app() -> Router {
@ -77,7 +79,7 @@ pub mod response;
#[cfg(test)]
mod tests {
use axum_lib as axum;
use axum_lib_0_7 as axum;
use axum::{
body::Body,
@ -155,7 +157,7 @@ mod tests {
);
let (_, body) = resp.into_parts();
let body = hyper::body::to_bytes(body).await.unwrap();
let body = axum::body::to_bytes(body, usize::MAX).await.unwrap();
assert_eq!(j.to_string().as_bytes(), body);
}

View File

@ -1,27 +1,21 @@
use axum_lib as axum;
use axum::{
body::{boxed, BoxBody},
http::Response,
response::IntoResponse,
};
use http::{header, StatusCode};
use hyper::body::Body;
use crate::binding::http::builder::adapter::to_response;
use crate::event::Event;
use axum::{body::Body, http::Response, response::IntoResponse};
use axum_lib_0_7 as axum;
use http::{header, StatusCode};
use http_1_1 as http;
impl IntoResponse for Event {
fn into_response(self) -> Response<BoxBody> {
fn into_response(self) -> Response<Body> {
match to_response(self) {
Ok(resp) => {
let (parts, body) = resp.into_parts();
Response::from_parts(parts, boxed(body))
Response::from_parts(parts, Body::new(body))
}
Err(err) => Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.header(header::CONTENT_TYPE, "text/plain")
.body(boxed(Body::from(err.to_string())))
.body(Body::from(err.to_string()))
.unwrap(),
}
}
@ -105,7 +99,7 @@ mod tests {
);
let (_, body) = resp.into_parts();
let body = hyper::body::to_bytes(body).await.unwrap();
let body = axum::body::to_bytes(body, usize::MAX).await.unwrap();
assert_eq!(fixtures::json_data_binary(), body);
}

View File

@ -1,15 +1,27 @@
#[cfg(feature = "axum")]
use bytes::Bytes;
use http::Response;
#[cfg(feature = "axum")]
use http_1_1 as http;
#[cfg(feature = "axum")]
use http_body_util::Full;
#[cfg(not(feature = "axum"))]
use hyper::body::Body;
use std::cell::Cell;
use crate::binding::http::{Builder, Serializer};
use crate::message::{BinaryDeserializer, Error, Result};
use crate::Event;
#[cfg(feature = "axum")]
use std::convert::Infallible;
#[cfg(feature = "axum")]
type BoxBody = http_body_util::combinators::UnsyncBoxBody<Bytes, Infallible>;
struct Adapter {
builder: Cell<http::response::Builder>,
}
#[cfg(not(feature = "axum"))]
impl Builder<Response<Body>> for Adapter {
fn header(&mut self, key: &str, value: http::header::HeaderValue) {
self.builder.set(self.builder.take().header(key, value));
@ -27,6 +39,27 @@ impl Builder<Response<Body>> for Adapter {
}
}
#[cfg(feature = "axum")]
impl Builder<Response<BoxBody>> for Adapter {
fn header(&mut self, key: &str, value: http::header::HeaderValue) {
self.builder.set(self.builder.take().header(key, value));
}
fn body(&mut self, bytes: Vec<u8>) -> Result<Response<BoxBody>> {
self.builder
.take()
.body(BoxBody::new(Full::from(bytes)))
.map_err(|e| crate::message::Error::Other {
source: Box::new(e),
})
}
fn finish(&mut self) -> Result<Response<BoxBody>> {
self.body(Vec::new())
}
}
#[cfg(not(feature = "axum"))]
pub fn to_response(event: Event) -> std::result::Result<Response<Body>, Error> {
BinaryDeserializer::deserialize_binary(
event,
@ -35,3 +68,13 @@ pub fn to_response(event: Event) -> std::result::Result<Response<Body>, Error> {
}),
)
}
#[cfg(feature = "axum")]
pub fn to_response(event: Event) -> std::result::Result<Response<BoxBody>, Error> {
BinaryDeserializer::deserialize_binary(
event,
Serializer::new(Adapter {
builder: Cell::new(http::Response::builder()),
}),
)
}

View File

@ -1,7 +1,9 @@
#[cfg(feature = "hyper")]
#[cfg(any(feature = "hyper", feature = "hyper-1-3"))]
pub mod adapter;
use crate::message::Result;
#[cfg(feature = "axum")]
use http_1_1 as http;
pub trait Builder<R> {
fn header(&mut self, key: &str, value: http::header::HeaderValue);

View File

@ -8,6 +8,8 @@ use crate::{
Result, StructuredDeserializer, StructuredSerializer,
},
};
#[cfg(feature = "axum")]
use http_1_1 as http;
use std::convert::TryFrom;
pub struct Deserializer<'a, T: Headers<'a>> {

View File

@ -1,4 +1,6 @@
use http::header::{AsHeaderName, HeaderMap, HeaderName, HeaderValue};
#[cfg(feature = "axum")]
use http_1_1 as http;
/// Any http library should be able to use the
/// [`to_event`](super::to_event) function with an implementation of

View File

@ -13,6 +13,8 @@ mod serializer;
pub use builder::Builder;
use core::convert::TryFrom;
use http::Response;
#[cfg(feature = "axum")]
use http_1_1 as http;
pub use serializer::Serializer;
use std::convert::TryInto;
use std::fmt::Debug;
@ -52,6 +54,8 @@ mod tests {
use crate::Event;
use core::convert::TryFrom;
use http::Response;
#[cfg(feature = "axum")]
use http_1_1 as http;
#[test]
fn test_response_to_event() {

View File

@ -12,6 +12,8 @@ use crate::message::{
};
use crate::Event;
use http::Request;
#[cfg(feature = "axum")]
use http_1_1 as http;
use std::convert::TryFrom;
use std::fmt::Debug;
@ -131,6 +133,8 @@ mod tests {
use crate::test::fixtures;
use bytes::Bytes;
use http::Request;
#[cfg(feature = "axum")]
use http_1_1 as http;
use std::convert::TryFrom;
#[test]

View File

@ -2,6 +2,18 @@
//!
//! Note: these APIs should be considered unstable and subject to changes.
#[cfg(all(
feature = "axum",
any(
feature = "http-binding",
feature = "actix",
feature = "reqwest",
feature = "warp",
feature = "poem"
)
))]
compile_error!("feature `axum` cannot be used with features `http-binding`, `actix`, `reqwest`, `warp`, or `poem`");
mod deserializer;
mod encoding;
mod error;