Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
sunli829 committed Mar 30, 2024
2 parents db15f1a + f6bec88 commit 2dc2bd4
Show file tree
Hide file tree
Showing 175 changed files with 566 additions and 572 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
# Switch to stable Rust
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.74.0
toolchain: 1.75.0
components: rustfmt, clippy
override: true
- name: Cache Rust
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
# Switch to stable Rust
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.74.0
toolchain: 1.75.0
components: rustfmt, clippy
- name: Cache Rust
uses: Swatinem/rust-cache@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
- name: Install Stable Toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.74.0
toolchain: 1.75.0
components: rustfmt
- name: Cache Rust
uses: Swatinem/rust-cache@v2
Expand Down
16 changes: 9 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ license = "MIT OR Apache-2.0"
documentation = "https://docs.rs/poem/"
homepage = "https://github.com/poem-web/poem"
repository = "https://github.com/poem-web/poem"
rust-version = "1.74"
rust-version = "1.75"

[workspace.dependencies]
poem = { path = "poem", version = "2.0.1", default-features = false }
poem-derive = { path = "poem-derive", version = "2.0.1" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "4.0.1" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.3.0" }
poem = { path = "poem", version = "3.0.0", default-features = false }
poem-derive = { path = "poem-derive", version = "3.0.0" }
poem-openapi-derive = { path = "poem-openapi-derive", version = "5.0.0" }
poem-grpc-build = { path = "poem-grpc-build", version = "0.4.0" }

proc-macro-crate = "3.0.0"
proc-macro2 = "1.0.29"
Expand All @@ -42,10 +42,12 @@ futures-util = "0.3.17"
tokio-stream = "0.1.8"
serde_yaml = "0.9"
quick-xml = { version = "0.31.0", features = ["serialize"] }
base64 = "0.21.0"
base64 = "0.22.0"
serde_urlencoded = "0.7.1"
indexmap = "2.0.0"
reqwest = { version = "0.11.23", default-features = false }
reqwest = { version = "0.12.2", default-features = false }
darling = "0.20.8"
static_assertions = "1.1.0"

# rustls, update together
rustls = "0.22.0"
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
<img src="https://img.shields.io/badge/unsafe-forbidden-success.svg?style=flat-square"
alt="Unsafe Rust forbidden" />
</a>
<a href="https://blog.rust-lang.org/2022/09/22/Rust-1.74.0.html">
<img src="https://img.shields.io/badge/rustc-1.74.0+-ab6000.svg"
alt="rustc 1.74.0+" />
<a href="https://blog.rust-lang.org/2023/11/16/Rust-1.75.0.html">
<img src="https://img.shields.io/badge/rustc-1.75.0+-ab6000.svg"
alt="rustc 1.75.0+" />
</a>
<a href="https://discord.gg/qWWNxwasb7">
<img src="https://img.shields.io/discord/932986985604333638.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2" />
Expand Down
1 change: 0 additions & 1 deletion examples/disabled/tonic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub mod hello_world {

pub struct MyGreeter;

#[tonic::async_trait]
impl Greeter for MyGreeter {
async fn say_hello(
&self,
Expand Down
1 change: 0 additions & 1 deletion examples/grpc/helloworld/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ poem_grpc::include_proto!("helloworld");

struct GreeterService;

#[poem::async_trait]
impl Greeter for GreeterService {
async fn say_hello(
&self,
Expand Down
1 change: 0 additions & 1 deletion examples/grpc/jsoncodec/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ poem_grpc::include_proto!("helloworld");

struct GreeterService;

#[poem::async_trait]
impl Greeter for GreeterService {
async fn say_hello(
&self,
Expand Down
1 change: 0 additions & 1 deletion examples/grpc/middleware/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ poem_grpc::include_proto!("helloworld");

struct GreeterService;

#[poem::async_trait]
impl Greeter for GreeterService {
async fn say_hello(
&self,
Expand Down
1 change: 0 additions & 1 deletion examples/grpc/reflection/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const FILE_DESCRIPTOR_SET: &[u8] = poem_grpc::include_file_descriptor_set!("hell

struct GreeterService;

#[poem::async_trait]
impl Greeter for GreeterService {
async fn say_hello(
&self,
Expand Down
1 change: 0 additions & 1 deletion examples/grpc/routeguide/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ struct RouteGuideService {
features: Arc<Vec<Feature>>,
}

#[poem::async_trait]
impl RouteGuide for RouteGuideService {
async fn get_feature(&self, request: Request<Point>) -> Result<Response<Feature>, Status> {
for feature in &self.features[..] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ publish.workspace = true
poem.workspace = true
poem-openapi.workspace = true
tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
reqwest = { version = "0.11.4", default-features = false, features = [
reqwest = { version = "0.12.2", default-features = false, features = [
"rustls-tls",
] }
tracing-subscriber.workspace = true
File renamed without changes.
3 changes: 3 additions & 0 deletions examples/openapi/auth-multiple/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ impl Api {
auth1: MyApiKeyAuthorization,
auth2: MyBasicAuthorization,
) -> Result<PlainText<String>> {
if auth1.0.username != "test" {
return Err(Error::from_status(StatusCode::UNAUTHORIZED));
}
if auth2.0.username != "test" || auth2.0.password != "123456" {
return Err(Error::from_status(StatusCode::UNAUTHORIZED));
}
Expand Down
3 changes: 1 addition & 2 deletions examples/openapi/content-type-accept/src/bcs_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ impl<T: Type> Payload for Bcs<T> {
}
}

#[poem::async_trait]
impl<T: Type + for<'b> Deserialize<'b>> ParsePayload for Bcs<T> {
const IS_REQUIRED: bool = true;

async fn from_request(request: &Request, body: &mut RequestBody) -> Result<Self> {
let data: Vec<u8> = FromRequest::from_request(request, body).await?;
let data = Vec::<u8>::from_request(request, body).await?;
let value: T = from_bytes(&data).map_err(|err| ParseRequestPayloadError {
reason: err.to_string(),
})?;
Expand Down
3 changes: 1 addition & 2 deletions examples/openapi/custom-payload/src/bcs_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,11 @@ impl<T: Type> Payload for Bcs<T> {
}
}

#[poem::async_trait]
impl<T: Type + for<'b> Deserialize<'b>> ParsePayload for Bcs<T> {
const IS_REQUIRED: bool = true;

async fn from_request(request: &Request, body: &mut RequestBody) -> Result<Self> {
let data: Vec<u8> = FromRequest::from_request(request, body).await?;
let data = Vec::<u8>::from_request(request, body).await?;
let value: T = from_bytes(&data).map_err(|err| ParseRequestPayloadError {
reason: err.to_string(),
})?;
Expand Down
1 change: 0 additions & 1 deletion examples/poem/basic-auth/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ struct BasicAuthEndpoint<E> {
password: String,
}

#[poem::async_trait]
impl<E: Endpoint> Endpoint for BasicAuthEndpoint<E> {
type Output = E::Output;

Expand Down
1 change: 0 additions & 1 deletion examples/poem/custom-extractor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use poem::{
struct Token(String);

// Implements a token extractor
#[poem::async_trait]
impl<'a> FromRequest<'a> for Token {
async fn from_request(req: &'a Request, _body: &mut RequestBody) -> Result<Self> {
let token = req
Expand Down
31 changes: 18 additions & 13 deletions examples/poem/local-server-with-browser/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ async fn main() -> Result<(), std::io::Error> {

// To test port assignment, run two instances of this example at once.
//
// For ports <1024, running with administrator priveleges would be needed on
// Unix. For port 0, the OS would assign a port and we'd need to find out
// For ports <1024, running with administrator priveledges would be needed
// on Unix. For port 0, the OS would assign a port and we'd need to find out
// what that port's number is.
let (min_port, max_port) = (8080, 8085);
// Using 127.0.0.1 instead of 0.0.0.0 for security; a local server should
Expand All @@ -32,25 +32,30 @@ async fn main() -> Result<(), std::io::Error> {
if port > max_port {
return Err(error.unwrap());
}
let listener = TcpListener::bind(format!("{hostname}:{}", port));
let listener = TcpListener::bind(format!("{hostname}:{port}"));
match listener.into_acceptor().await {
Ok(a) => break a,
Err(err) => {
// Most likely, another application is bound to this port.
eprintln!("Couldn't bind to port {port}.");
error = Some(err)
}
Err(err) => error = Some(err),
};
// Most likely, another application is bound to this port.
eprintln!("Couldn't bind to port {port}.");
port += 1;
};

// Now that the acceptor exists, the browser should be able to connect
eprintln!("Listening at {hostname}:{port}.");
let http_address = format!("http://{hostname}:{port}/");
eprintln!("Listening at {http_address}.");
eprint!("Trying to launch a browser at {http_address}...");
match open::that(&http_address) {
Ok(_) => eprintln!(" Success!"),
Err(err) => eprintln!("\nFailed to launch a browser: {err}"),
eprintln!("Trying to launch a browser at {http_address}...");
// We use `open::that_detached` so that launching, for example, a new
// instance of firefox on Linux does not block. This will report success
// even if the browser exits with a non-zero error code.
//
// You can alternatively consider using `tokio::spawn_blocking` and
// `open::that`. Note that in cases when `open::that` blocks, exiting the
// server process may also kill the browser process.
match open::that_detached(&http_address) {
Ok(()) => { /* Ok() doesn't mean much with `that_detached`. */ }
Err(err) => eprintln!("Failed to launch a browser: {err}"),
}

Server::new_with_acceptor(acceptor).run(app).await?;
Expand Down
5 changes: 2 additions & 3 deletions examples/poem/middleware/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use poem::{
async_trait, get, handler, listener::TcpListener, Endpoint, EndpointExt, IntoResponse,
Middleware, Request, Response, Result, Route, Server,
get, handler, listener::TcpListener, Endpoint, EndpointExt, IntoResponse, Middleware, Request,
Response, Result, Route, Server,
};

struct Log;
Expand All @@ -15,7 +15,6 @@ impl<E: Endpoint> Middleware<E> for Log {

struct LogImpl<E>(E);

#[async_trait]
impl<E: Endpoint> Endpoint for LogImpl<E> {
type Output = Response;

Expand Down
10 changes: 5 additions & 5 deletions examples/poem/opentelemetry-jaeger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ publish.workspace = true
poem = { workspace = true, features = ["opentelemetry"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tracing-subscriber.workspace = true
opentelemetry = { version = "0.21.0", features = ["metrics"] }
opentelemetry_sdk = { version = "0.21.0", features = ["rt-tokio"] }
opentelemetry-http = { version = "0.10.0" }
opentelemetry-otlp = { version = "0.14.0", features = [
opentelemetry = { version = "0.22.0", features = ["metrics"] }
opentelemetry_sdk = { version = "0.22.0", features = ["rt-tokio"] }
opentelemetry-http = { version = "0.11.0" }
opentelemetry-otlp = { version = "0.15.0", features = [
"trace",
] }
reqwest = "0.11.6"
reqwest = "0.11"

[[bin]]
name = "example-opentelemetry-client"
Expand Down
2 changes: 1 addition & 1 deletion examples/poem/redis-session/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ publish.workspace = true
poem = { workspace = true, features = ["redis-session"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tracing-subscriber.workspace = true
redis = { version = "0.24.0", features = ["aio", "tokio-comp", "connection-manager"] }
redis = { version = "0.25.2", features = ["aio", "tokio-comp", "connection-manager"] }
2 changes: 1 addition & 1 deletion poem-derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-derive"
version = "2.0.1"
version = "3.0.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
1 change: 0 additions & 1 deletion poem-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ fn generate_handler(internal: bool, input: TokenStream) -> Result<TokenStream> {
#[allow(non_camel_case_types)]
#def_struct

#[#crate_name::async_trait]
impl #impl_generics #crate_name::Endpoint for #ident #type_generics #where_clause {
type Output = #crate_name::Response;

Expand Down
2 changes: 1 addition & 1 deletion poem-grpc-build/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-grpc-build"
version = "0.3.0"
version = "0.4.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion poem-grpc-build/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub(crate) fn generate(config: &GrpcConfig, service: &Service, buf: &mut String)

pub fn with<M>(mut self, middleware: M) -> Self
where
M: ::poem::Middleware<::std::sync::Arc<dyn ::poem::Endpoint<Output = ::poem::Response> + 'static>>,
M: ::poem::Middleware<::std::sync::Arc<dyn ::poem::endpoint::DynEndpoint<Output = ::poem::Response> + 'static>>,
M::Output: 'static,
{
self.cli = self.cli.with(middleware);
Expand Down
13 changes: 4 additions & 9 deletions poem-grpc-build/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,25 @@ pub(crate) fn generate(config: &GrpcConfig, service: &Service, buf: &mut String)
match (method.client_streaming, method.server_streaming) {
(false, false) => {
trait_methods.push(quote! {
async fn #method_ident(&self, request: #crate_name::Request<#input_type>) -> ::std::result::Result<#crate_name::Response<#output_type>, #crate_name::Status>;
fn #method_ident(&self, request: #crate_name::Request<#input_type>) -> impl ::std::future::Future<Output = ::std::result::Result<#crate_name::Response<#output_type>, #crate_name::Status>> + Send;
});
endpoints.push(generate_unary(&codec_list, method_info));
}
(true, false) => {
trait_methods.push(quote! {
async fn #method_ident(&self, request: #crate_name::Request<#crate_name::Streaming<#input_type>>) -> ::std::result::Result<#crate_name::Response<#output_type>, #crate_name::Status>;
fn #method_ident(&self, request: #crate_name::Request<#crate_name::Streaming<#input_type>>) -> impl ::std::future::Future<Output = ::std::result::Result<#crate_name::Response<#output_type>, #crate_name::Status>> + Send;
});
endpoints.push(generate_client_streaming(&codec_list, method_info));
}
(false, true) => {
trait_methods.push(quote! {
async fn #method_ident(&self, request: #crate_name::Request<#input_type>) -> ::std::result::Result<#crate_name::Response<#crate_name::Streaming<#output_type>>, #crate_name::Status>;
fn #method_ident(&self, request: #crate_name::Request<#input_type>) -> impl ::std::future::Future<Output = ::std::result::Result<#crate_name::Response<#crate_name::Streaming<#output_type>>, #crate_name::Status>> + Send;
});
endpoints.push(generate_server_streaming(&codec_list, method_info));
}
(true, true) => {
trait_methods.push(quote! {
async fn #method_ident(&self, request: #crate_name::Request<#crate_name::Streaming<#input_type>>) -> ::std::result::Result<#crate_name::Response<#crate_name::Streaming<#output_type>>, #crate_name::Status>;
fn #method_ident(&self, request: #crate_name::Request<#crate_name::Streaming<#input_type>>) -> impl ::std::future::Future<Output = ::std::result::Result<#crate_name::Response<#crate_name::Streaming<#output_type>>, #crate_name::Status>> + Send;
});
endpoints.push(generate_bidirectional_streaming(&codec_list, method_info));
}
Expand All @@ -94,7 +94,6 @@ pub(crate) fn generate(config: &GrpcConfig, service: &Service, buf: &mut String)

let token_stream = quote! {
#[allow(unused_imports)]
#[::poem::async_trait]
pub trait #service_ident: Send + Sync + 'static {
#(#trait_methods)*
}
Expand Down Expand Up @@ -200,7 +199,6 @@ fn generate_unary(codec_list: &[Path], method_info: MethodInfo) -> TokenStream {
#[allow(non_camel_case_types)]
struct #proxy_service_ident<T>(::std::sync::Arc<T>);

#[::poem::async_trait]
impl<T: #service_ident> #crate_name::service::UnaryService<#input_type> for #proxy_service_ident<T> {
type Response = #output_type;

Expand Down Expand Up @@ -245,7 +243,6 @@ fn generate_client_streaming(codec_list: &[Path], method_info: MethodInfo) -> To
#[allow(non_camel_case_types)]
struct #proxy_service_ident<T>(::std::sync::Arc<T>);

#[::poem::async_trait]
impl<T: #service_ident> #crate_name::service::ClientStreamingService<#input_type> for #proxy_service_ident<T> {
type Response = #output_type;

Expand Down Expand Up @@ -290,7 +287,6 @@ fn generate_server_streaming(codec_list: &[Path], method_info: MethodInfo) -> To
#[allow(non_camel_case_types)]
struct #proxy_service_ident<T>(::std::sync::Arc<T>);

#[::poem::async_trait]
impl<T: #service_ident> #crate_name::service::ServerStreamingService<#input_type> for #proxy_service_ident<T> {
type Response = #output_type;

Expand Down Expand Up @@ -335,7 +331,6 @@ fn generate_bidirectional_streaming(codec_list: &[Path], method_info: MethodInfo
#[allow(non_camel_case_types)]
struct #proxy_service_ident<T>(::std::sync::Arc<T>);

#[::poem::async_trait]
impl<T: #service_ident> #crate_name::service::BidirectionalStreamingService<#input_type> for #proxy_service_ident<T> {
type Response = #output_type;

Expand Down
4 changes: 2 additions & 2 deletions poem-grpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-grpc"
version = "0.3.0"
version = "0.4.0"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down Expand Up @@ -28,7 +28,7 @@ itoa = "1.0.2"
percent-encoding = "2.1.0"
bytes.workspace = true
prost = "0.12.0"
base64 = "0.21.0"
base64.workspace = true
prost-types = "0.12.0"
tokio-stream = { workspace = true, features = ["sync"] }
serde = { workspace = true, optional = true }
Expand Down
Loading

0 comments on commit 2dc2bd4

Please sign in to comment.