mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-01 08:56:15 +01:00
parent
37478772bc
commit
6a4825bb22
3 changed files with 40 additions and 38 deletions
|
@ -7,7 +7,9 @@ and this project adheres to [Semantic Versioning].
|
||||||
|
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- None.
|
- **breaking:** Change casing of `ProtoBuf` to `Protobuf` ([#1595])
|
||||||
|
|
||||||
|
[#1595]: https://github.com/tokio-rs/axum/pull/1595
|
||||||
|
|
||||||
# 0.5.0 (12. February, 2022)
|
# 0.5.0 (12. February, 2022)
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//! `erased-json` | Enables the `ErasedJson` response | No
|
//! `erased-json` | Enables the `ErasedJson` response | No
|
||||||
//! `form` | Enables the `Form` extractor | No
|
//! `form` | Enables the `Form` extractor | No
|
||||||
//! `json-lines` | Enables the `JsonLines` extractor and response | No
|
//! `json-lines` | Enables the `JsonLines` extractor and response | No
|
||||||
//! `protobuf` | Enables the `ProtoBuf` extractor and response | No
|
//! `protobuf` | Enables the `Protobuf` extractor and response | No
|
||||||
//! `query` | Enables the `Query` extractor | No
|
//! `query` | Enables the `Query` extractor | No
|
||||||
//! `spa` | Enables the `Spa` router | No
|
//! `spa` | Enables the `Spa` router | No
|
||||||
//! `typed-routing` | Enables the `TypedPath` routing utilities | No
|
//! `typed-routing` | Enables the `TypedPath` routing utilities | No
|
||||||
|
|
|
@ -19,13 +19,13 @@ use std::ops::{Deref, DerefMut};
|
||||||
/// # As extractor
|
/// # As extractor
|
||||||
///
|
///
|
||||||
/// When used as an extractor, it can decode request bodies into some type that
|
/// When used as an extractor, it can decode request bodies into some type that
|
||||||
/// implements [`prost::Message`]. The request will be rejected (and a [`ProtoBufRejection`] will
|
/// implements [`prost::Message`]. The request will be rejected (and a [`ProtobufRejection`] will
|
||||||
/// be returned) if:
|
/// be returned) if:
|
||||||
///
|
///
|
||||||
/// - The body couldn't be decoded into the target Protocol Buffer message type.
|
/// - The body couldn't be decoded into the target Protocol Buffer message type.
|
||||||
/// - Buffering the request body fails.
|
/// - Buffering the request body fails.
|
||||||
///
|
///
|
||||||
/// See [`ProtoBufRejection`] for more details.
|
/// See [`ProtobufRejection`] for more details.
|
||||||
///
|
///
|
||||||
/// The extractor does not expect a `Content-Type` header to be present in the request.
|
/// The extractor does not expect a `Content-Type` header to be present in the request.
|
||||||
///
|
///
|
||||||
|
@ -33,7 +33,7 @@ use std::ops::{Deref, DerefMut};
|
||||||
///
|
///
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// use axum::{routing::post, Router};
|
/// use axum::{routing::post, Router};
|
||||||
/// use axum_extra::protobuf::ProtoBuf;
|
/// use axum_extra::protobuf::Protobuf;
|
||||||
///
|
///
|
||||||
/// #[derive(prost::Message)]
|
/// #[derive(prost::Message)]
|
||||||
/// struct CreateUser {
|
/// struct CreateUser {
|
||||||
|
@ -43,7 +43,7 @@ use std::ops::{Deref, DerefMut};
|
||||||
/// password: String,
|
/// password: String,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// async fn create_user(ProtoBuf(payload): ProtoBuf<CreateUser>) {
|
/// async fn create_user(Protobuf(payload): Protobuf<CreateUser>) {
|
||||||
/// // payload is `CreateUser`
|
/// // payload is `CreateUser`
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
@ -69,7 +69,7 @@ use std::ops::{Deref, DerefMut};
|
||||||
/// routing::get,
|
/// routing::get,
|
||||||
/// Router,
|
/// Router,
|
||||||
/// };
|
/// };
|
||||||
/// use axum_extra::protobuf::ProtoBuf;
|
/// use axum_extra::protobuf::Protobuf;
|
||||||
///
|
///
|
||||||
/// #[derive(prost::Message)]
|
/// #[derive(prost::Message)]
|
||||||
/// struct User {
|
/// struct User {
|
||||||
|
@ -77,9 +77,9 @@ use std::ops::{Deref, DerefMut};
|
||||||
/// username: String,
|
/// username: String,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// async fn get_user(Path(user_id) : Path<String>) -> ProtoBuf<User> {
|
/// async fn get_user(Path(user_id) : Path<String>) -> Protobuf<User> {
|
||||||
/// let user = find_user(user_id).await;
|
/// let user = find_user(user_id).await;
|
||||||
/// ProtoBuf(user)
|
/// Protobuf(user)
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// async fn find_user(user_id: String) -> User {
|
/// async fn find_user(user_id: String) -> User {
|
||||||
|
@ -94,10 +94,10 @@ use std::ops::{Deref, DerefMut};
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
#[cfg_attr(docsrs, doc(cfg(feature = "protobuf")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "protobuf")))]
|
||||||
pub struct ProtoBuf<T>(pub T);
|
pub struct Protobuf<T>(pub T);
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl<T, S, B> FromRequest<S, B> for ProtoBuf<T>
|
impl<T, S, B> FromRequest<S, B> for Protobuf<T>
|
||||||
where
|
where
|
||||||
T: Message + Default,
|
T: Message + Default,
|
||||||
B: HttpBody + Send + 'static,
|
B: HttpBody + Send + 'static,
|
||||||
|
@ -105,19 +105,19 @@ where
|
||||||
B::Error: Into<BoxError>,
|
B::Error: Into<BoxError>,
|
||||||
S: Send + Sync,
|
S: Send + Sync,
|
||||||
{
|
{
|
||||||
type Rejection = ProtoBufRejection;
|
type Rejection = ProtobufRejection;
|
||||||
|
|
||||||
async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
|
async fn from_request(req: Request<B>, state: &S) -> Result<Self, Self::Rejection> {
|
||||||
let mut bytes = Bytes::from_request(req, state).await?;
|
let mut bytes = Bytes::from_request(req, state).await?;
|
||||||
|
|
||||||
match T::decode(&mut bytes) {
|
match T::decode(&mut bytes) {
|
||||||
Ok(value) => Ok(ProtoBuf(value)),
|
Ok(value) => Ok(Protobuf(value)),
|
||||||
Err(err) => Err(ProtoBufDecodeError::from_err(err).into()),
|
Err(err) => Err(ProtobufDecodeError::from_err(err).into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Deref for ProtoBuf<T> {
|
impl<T> Deref for Protobuf<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
|
@ -125,19 +125,19 @@ impl<T> Deref for ProtoBuf<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> DerefMut for ProtoBuf<T> {
|
impl<T> DerefMut for Protobuf<T> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<T> for ProtoBuf<T> {
|
impl<T> From<T> for Protobuf<T> {
|
||||||
fn from(inner: T) -> Self {
|
fn from(inner: T) -> Self {
|
||||||
Self(inner)
|
Self(inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> IntoResponse for ProtoBuf<T>
|
impl<T> IntoResponse for Protobuf<T>
|
||||||
where
|
where
|
||||||
T: Message + Default,
|
T: Message + Default,
|
||||||
{
|
{
|
||||||
|
@ -150,13 +150,13 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rejection type for [`ProtoBuf`].
|
/// Rejection type for [`Protobuf`].
|
||||||
///
|
///
|
||||||
/// This rejection is used if the request body couldn't be decoded into the target type.
|
/// This rejection is used if the request body couldn't be decoded into the target type.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ProtoBufDecodeError(pub(crate) axum::Error);
|
pub struct ProtobufDecodeError(pub(crate) axum::Error);
|
||||||
|
|
||||||
impl ProtoBufDecodeError {
|
impl ProtobufDecodeError {
|
||||||
pub(crate) fn from_err<E>(err: E) -> Self
|
pub(crate) fn from_err<E>(err: E) -> Self
|
||||||
where
|
where
|
||||||
E: Into<axum::BoxError>,
|
E: Into<axum::BoxError>,
|
||||||
|
@ -165,53 +165,53 @@ impl ProtoBufDecodeError {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for ProtoBufDecodeError {
|
impl std::fmt::Display for ProtobufDecodeError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "Failed to decode the body: {:?}", self.0)
|
write!(f, "Failed to decode the body: {:?}", self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::error::Error for ProtoBufDecodeError {
|
impl std::error::Error for ProtobufDecodeError {
|
||||||
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
||||||
Some(&self.0)
|
Some(&self.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoResponse for ProtoBufDecodeError {
|
impl IntoResponse for ProtobufDecodeError {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
StatusCode::UNPROCESSABLE_ENTITY.into_response()
|
StatusCode::UNPROCESSABLE_ENTITY.into_response()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rejection used for [`ProtoBuf`].
|
/// Rejection used for [`Protobuf`].
|
||||||
///
|
///
|
||||||
/// Contains one variant for each way the [`ProtoBuf`] extractor
|
/// Contains one variant for each way the [`Protobuf`] extractor
|
||||||
/// can fail.
|
/// can fail.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub enum ProtoBufRejection {
|
pub enum ProtobufRejection {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
ProtoBufDecodeError(ProtoBufDecodeError),
|
ProtobufDecodeError(ProtobufDecodeError),
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
BytesRejection(BytesRejection),
|
BytesRejection(BytesRejection),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ProtoBufDecodeError> for ProtoBufRejection {
|
impl From<ProtobufDecodeError> for ProtobufRejection {
|
||||||
fn from(inner: ProtoBufDecodeError) -> Self {
|
fn from(inner: ProtobufDecodeError) -> Self {
|
||||||
Self::ProtoBufDecodeError(inner)
|
Self::ProtobufDecodeError(inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BytesRejection> for ProtoBufRejection {
|
impl From<BytesRejection> for ProtobufRejection {
|
||||||
fn from(inner: BytesRejection) -> Self {
|
fn from(inner: BytesRejection) -> Self {
|
||||||
Self::BytesRejection(inner)
|
Self::BytesRejection(inner)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoResponse for ProtoBufRejection {
|
impl IntoResponse for ProtobufRejection {
|
||||||
fn into_response(self) -> Response {
|
fn into_response(self) -> Response {
|
||||||
match self {
|
match self {
|
||||||
Self::ProtoBufDecodeError(inner) => inner.into_response(),
|
Self::ProtobufDecodeError(inner) => inner.into_response(),
|
||||||
Self::BytesRejection(inner) => inner.into_response(),
|
Self::BytesRejection(inner) => inner.into_response(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,7 @@ mod tests {
|
||||||
|
|
||||||
let app = Router::new().route(
|
let app = Router::new().route(
|
||||||
"/",
|
"/",
|
||||||
post(|input: ProtoBuf<Input>| async move { input.foo.to_owned() }),
|
post(|input: Protobuf<Input>| async move { input.foo.to_owned() }),
|
||||||
);
|
);
|
||||||
|
|
||||||
let input = Input {
|
let input = Input {
|
||||||
|
@ -263,7 +263,7 @@ mod tests {
|
||||||
test: i32,
|
test: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
let app = Router::new().route("/", post(|_: ProtoBuf<Expected>| async {}));
|
let app = Router::new().route("/", post(|_: Protobuf<Expected>| async {}));
|
||||||
|
|
||||||
let input = Input {
|
let input = Input {
|
||||||
foo: "bar".to_owned(),
|
foo: "bar".to_owned(),
|
||||||
|
@ -291,12 +291,12 @@ mod tests {
|
||||||
|
|
||||||
let app = Router::new().route(
|
let app = Router::new().route(
|
||||||
"/",
|
"/",
|
||||||
post(|input: ProtoBuf<Input>| async move {
|
post(|input: Protobuf<Input>| async move {
|
||||||
let output = Output {
|
let output = Output {
|
||||||
result: input.foo.to_owned(),
|
result: input.foo.to_owned(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ProtoBuf(output)
|
Protobuf(output)
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue