Skip to content

Commit

Permalink
Add support for http-body v1
Browse files Browse the repository at this point in the history
  • Loading branch information
nwtgck committed Jan 14, 2024
1 parent 781529a commit 1891b38
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ Note: In this file, do not use the hard wrap in the middle of a sentence for com

## [Unreleased]

- Add support for `http_body1::Body`.

## [0.8.3] - 2023-10-21

- Update to [new coroutine API since nightly-2023-10-21](https://github.com/rust-lang/rust/pull/116958). This renames unstable `generator_trait` feature to `coroutine_trait`. The old cargo feature name is kept as a deprecated alias and will be removed in the next breaking release. ([daf9165](https://github.com/taiki-e/auto_enums/commit/daf91653b925d53cde57b598f0d884fe35a53c60))
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ tokio03 = []
tokio02 = []
# https://docs.rs/tokio/0.1
tokio01 = []
# https://docs.rs/http-body/1
http_body1 = []

# ==============================================================================
# Unstable features
Expand Down Expand Up @@ -98,6 +100,7 @@ tokio02_crate = { package = "tokio", version = "0.2", default-features = false }
tokio01_crate = { package = "tokio", version = "0.1", default-features = false, features = ["io"] }
rayon_crate = { package = "rayon", version = "1" }
serde_crate = { package = "serde", version = "1" }
http_body1_crate = { package = "http-body", version = "1", default-features = false }

[lints]
workspace = true
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ traits to `#[derive]`.

`#[enum_derive]` supports many of the standard library traits and some popular
third-party libraries traits such as [rayon], [futures][futures03],
[tokio][tokio1]. **See [documentation](https://docs.rs/auto_enums/latest/auto_enums/#supported-traits) for a complete list of supported traits.**
[tokio][tokio1], [http_body][http_body1]. **See [documentation](https://docs.rs/auto_enums/latest/auto_enums/#supported-traits) for a complete list of supported traits.**

If you want to use traits that are not supported by `#[enum_derive]`, you
can use another crate that provides [derives macros][proc-macro-derive], or
Expand Down Expand Up @@ -165,6 +165,8 @@ enum Foo<A, B> {
- **`trusted_len`**
- Enable to use `[std|core]::iter::TrustedLen` trait.
- Note that this feature is unstable and may cause incompatible changes between patch versions.
- **`http_body1`**
- Enable to use [http_body v1][http_body1] traits.

### `type_analysis` feature

Expand Down Expand Up @@ -218,6 +220,7 @@ Please be careful if you return another traits with the same name.
[tokio02]: https://docs.rs/tokio/0.2
[tokio03]: https://docs.rs/tokio/0.3
[tokio1]: https://docs.rs/tokio/1
[http_body1]: https://docs.rs/http_body/1

## License

Expand Down
48 changes: 48 additions & 0 deletions src/derive/external/http_body1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

pub(crate) mod body {
use quote::ToTokens;

use crate::derive::*;

pub(crate) const NAME: &[&str] = &["http_body1::Body"];

pub(crate) fn derive(cx: &Context, data: &Data) -> Result<TokenStream> {
cx.needs_pin_projection();

let ident = &data.ident;
let pin = quote!(::core::pin::Pin);
let trait_: syn::Path = parse_quote!(::http_body::Body);
let mut impl_ = EnumImpl::from_trait(data, trait_.clone(), None, parse_quote! {
trait Body {
type Data;
type Error;
#[inline]
fn is_end_stream(&self) -> bool;
#[inline]
fn size_hint(&self) -> ::http_body::SizeHint;
}
})
.build_impl();

let poll_frame = data
.variant_idents()
.map(|v| quote!(#ident::#v(x) => #trait_::poll_frame(#pin::new_unchecked(x), cx)));
impl_.items.push(parse_quote! {
fn poll_frame(
self: #pin<&mut Self>,
cx: &mut ::core::task::Context<'_>,
) -> ::core::task::Poll<
::core::option::Option<
::core::result::Result<::http_body::Frame<Self::Data>, Self::Error>,
>,
> {
unsafe {
match self.get_unchecked_mut() { #(#poll_frame,)* }
}
}
});

Ok(impl_.into_token_stream())
}
}
3 changes: 3 additions & 0 deletions src/derive/external/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,6 @@ pub(crate) mod tokio03;
// https://docs.rs/tokio/1
#[cfg(feature = "tokio1")]
pub(crate) mod tokio1;
// https://docs.rs/http-body/1
#[cfg(feature = "http_body1")]
pub(crate) mod http_body1;
3 changes: 3 additions & 0 deletions src/enum_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ fn get_derive(s: &str) -> Option<DeriveFn> {
external::tokio01::async_read,
#[cfg(feature = "tokio01")]
external::tokio01::async_write,
// http_body1
#[cfg(feature = "http_body1")]
external::http_body1::body,
}

None
Expand Down
5 changes: 5 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,10 @@ fn func(x: i32) -> impl ParallelIterator {
- [`tokio01::AsyncRead`](https://docs.rs/tokio/0.1/tokio/io/trait.AsyncRead.html)
- [`tokio01::AsyncWrite`](https://docs.rs/tokio/0.1/tokio/io/trait.AsyncWrite.html)
### [http_body v1][http_body1] *(requires `"http_body1"` crate feature)*
- [`http_body1::Body`](https://docs.rs/http-body/1/http_body/trait.Body.html) - [example](https://github.com/taiki-e/auto_enums/blob/HEAD/tests/expand/external/http_body/body.rs) | [generated code](https://github.com/taiki-e/auto_enums/blob/HEAD/tests/expand/external/http_body/body.expanded.rs)
## Inherent methods
These don't derive traits, but derive inherent methods instead.
Expand Down Expand Up @@ -859,6 +863,7 @@ Please be careful if you return another traits with the same name.
[tokio02]: https://docs.rs/tokio/0.2
[tokio03]: https://docs.rs/tokio/0.3
[tokio1]: https://docs.rs/tokio/1
[http_body1]: https://docs.rs/http-body/1
*/

#![doc(test(
Expand Down
1 change: 1 addition & 0 deletions tests/compiletest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
feature = "tokio02",
feature = "tokio03",
feature = "tokio1",
feature = "http_body1",
))]

#[rustversion::attr(not(nightly), ignore)]
Expand Down
62 changes: 62 additions & 0 deletions tests/expand/external/http_body/body.expanded.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
extern crate http_body1_crate as http_body;
use auto_enums::enum_derive;
enum Enum<A, B> {
A(A),
B(B),
}
impl<A, B> ::http_body::Body for Enum<A, B>
where
A: ::http_body::Body,
B: ::http_body::Body<
Data = <A as ::http_body::Body>::Data,
Error = <A as ::http_body::Body>::Error,
>,
{
type Data = <A as ::http_body::Body>::Data;
type Error = <A as ::http_body::Body>::Error;
#[inline]
fn is_end_stream(&self) -> bool {
match self {
Enum::A(x) => ::http_body::Body::is_end_stream(x),
Enum::B(x) => ::http_body::Body::is_end_stream(x),
}
}
#[inline]
fn size_hint(&self) -> ::http_body::SizeHint {
match self {
Enum::A(x) => ::http_body::Body::size_hint(x),
Enum::B(x) => ::http_body::Body::size_hint(x),
}
}
fn poll_frame(
self: ::core::pin::Pin<&mut Self>,
cx: &mut ::core::task::Context<'_>,
) -> ::core::task::Poll<
::core::option::Option<
::core::result::Result<::http_body::Frame<Self::Data>, Self::Error>,
>,
> {
unsafe {
match self.get_unchecked_mut() {
Enum::A(x) => {
::http_body::Body::poll_frame(::core::pin::Pin::new_unchecked(x), cx)
}
Enum::B(x) => {
::http_body::Body::poll_frame(::core::pin::Pin::new_unchecked(x), cx)
}
}
}
}
}
impl<A, B> ::core::marker::Unpin for Enum<A, B>
where
A: ::core::marker::Unpin,
B: ::core::marker::Unpin,
{}
const _: () = {
trait MustNotImplDrop {}
#[allow(clippy::drop_bounds, drop_bounds)]
impl<T: ::core::ops::Drop> MustNotImplDrop for T {}
impl<A, B> MustNotImplDrop for Enum<A, B> {}
};
fn main() {}
13 changes: 13 additions & 0 deletions tests/expand/external/http_body/body.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

extern crate http_body1_crate as http_body;

use auto_enums::enum_derive;

#[enum_derive(http_body1::Body)]
enum Enum<A, B> {
A(A),
B(B),
}

fn main() {}
13 changes: 13 additions & 0 deletions tests/run-pass/http_body1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: Apache-2.0 OR MIT

extern crate http_body1_crate as http_body;

use auto_enums::enum_derive;

#[enum_derive(http_body1::Body)]
enum HttpBody1<A, B> {
A(A),
B(B),
}

fn main() {}

0 comments on commit 1891b38

Please sign in to comment.