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 Jan 4, 2025
2 parents 43c6601 + 658f7de commit 4537234
Show file tree
Hide file tree
Showing 39 changed files with 283 additions and 66 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ tokio = "1.39.1"
serde_json = "1.0.68"
sonic-rs = "0.3.5"
serde = { version = "1.0.130", features = ["derive"] }
thiserror = "1.0.30"
thiserror = "2.0"
regex = "1.5.5"
mime = "0.3.16"
tracing = "0.1.36"
Expand Down
14 changes: 14 additions & 0 deletions examples/grpc/helloworld_typename/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "example-grpc-helloworld-typename"
version.workspace = true
edition.workspace = true
publish.workspace = true

[dependencies]
poem.workspace = true
poem-grpc.workspace = true
prost.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }

[build-dependencies]
poem-grpc-build.workspace = true
9 changes: 9 additions & 0 deletions examples/grpc/helloworld_typename/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use std::io::Result;

use poem_grpc_build::Config;

fn main() -> Result<()> {
Config::new()
.enable_type_names()
.compile(&["./proto/helloworld.proto"], &["./proto"])
}
37 changes: 37 additions & 0 deletions examples/grpc/helloworld_typename/proto/helloworld.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
string name = 1;
}

// The response message containing the greetings
message HelloReply {
string message = 1;
}
18 changes: 18 additions & 0 deletions examples/grpc/helloworld_typename/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use prost::Name;

poem_grpc::include_proto!("helloworld");

fn main() -> Result<(), std::io::Error> {
println!(
"HelloRequest has {} full name and {} type url",
HelloRequest::full_name(),
HelloRequest::type_url()
);
println!(
"HelloReply has {} full name and {} type url",
HelloReply::full_name(),
HelloReply::type_url()
);

Ok(())
}
2 changes: 1 addition & 1 deletion examples/poem/custom-error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ publish.workspace = true
poem.workspace = true
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
tracing-subscriber.workspace = true
thiserror = "1.0.30"
thiserror = "2.0"
6 changes: 6 additions & 0 deletions poem-grpc-build/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,12 @@ impl Config {
self
}

/// Enable auto implementation of the `prost::Name` trait
pub fn enable_type_names(mut self) -> Self {
self.prost_config.enable_type_names();
self
}

/// When set, the `FileDescriptorSet` generated by `protoc` is written to
/// the provided filesystem path.
pub fn file_descriptor_set_path(mut self, path: impl AsRef<Path>) -> Self {
Expand Down
4 changes: 4 additions & 0 deletions poem-grpc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

# [0.5.3] 2024-01-04

- feat: Implement enable_type_name config method [#924](https://github.com/poem-web/poem/pull/924)

# [0.5.2] 2024-11-20

- Add `ClientConfigBuilder::http2_max_header_list_size` method to set the max size of received header frames.
Expand Down
2 changes: 1 addition & 1 deletion poem-grpc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-grpc"
version = "0.5.2"
version = "0.5.3"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion poem-grpc/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ pub struct GetBinaryAll<'a> {
iter: poem::http::header::ValueIter<'a, HeaderValue>,
}

impl<'a> Iterator for GetBinaryAll<'a> {
impl Iterator for GetBinaryAll<'_> {
type Item = Vec<u8>;

fn next(&mut self) -> Option<Self::Item> {
Expand Down
70 changes: 70 additions & 0 deletions poem-openapi-derive/src/common_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,76 @@ pub(crate) struct ExtraHeader {
pub(crate) deprecated: bool,
}

pub(crate) enum LitOrPath<T> {
Lit(T),
Path(syn::Path),
}

impl<T> darling::FromMeta for LitOrPath<T>
where
T: darling::FromMeta,
{
fn from_nested_meta(item: &darling::ast::NestedMeta) -> darling::Result<Self> {
T::from_nested_meta(item)
.map(Self::Lit)
.or_else(|_| syn::Path::from_nested_meta(item).map(Self::Path))
}

fn from_meta(item: &syn::Meta) -> darling::Result<Self> {
T::from_meta(item)
.map(Self::Lit)
.or_else(|_| syn::Path::from_meta(item).map(Self::Path))
}

fn from_none() -> Option<Self> {
T::from_none()
.map(Self::Lit)
.or_else(|| syn::Path::from_none().map(Self::Path))
}

fn from_word() -> darling::Result<Self> {
T::from_word()
.map(Self::Lit)
.or_else(|_| syn::Path::from_word().map(Self::Path))
}

fn from_list(items: &[darling::ast::NestedMeta]) -> darling::Result<Self> {
T::from_list(items)
.map(Self::Lit)
.or_else(|_| syn::Path::from_list(items).map(Self::Path))
}

fn from_value(value: &Lit) -> darling::Result<Self> {
T::from_value(value)
.map(Self::Lit)
.or_else(|_| syn::Path::from_value(value).map(Self::Path))
}

fn from_expr(expr: &syn::Expr) -> darling::Result<Self> {
T::from_expr(expr)
.map(Self::Lit)
.or_else(|_| syn::Path::from_expr(expr).map(Self::Path))
}

fn from_char(value: char) -> darling::Result<Self> {
T::from_char(value)
.map(Self::Lit)
.or_else(|_| syn::Path::from_char(value).map(Self::Path))
}

fn from_string(value: &str) -> darling::Result<Self> {
T::from_string(value)
.map(Self::Lit)
.or_else(|_| syn::Path::from_string(value).map(Self::Path))
}

fn from_bool(value: bool) -> darling::Result<Self> {
T::from_bool(value)
.map(Self::Lit)
.or_else(|_| syn::Path::from_bool(value).map(Self::Path))
}
}

#[derive(FromMeta)]
pub(crate) struct CodeSample {
pub(crate) lang: String,
Expand Down
33 changes: 20 additions & 13 deletions poem-openapi-derive/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use quote::quote;
use syn::{Attribute, DeriveInput, Error, Generics, Path, Type};

use crate::{
common_args::ExtraHeader,
common_args::{ExtraHeader, LitOrPath},
error::GeneratorResult,
utils::{get_crate_name, get_description, optional_literal, optional_literal_string},
};
Expand All @@ -33,7 +33,7 @@ struct ResponseItem {
fields: Fields<ResponseField>,

#[darling(default)]
status: Option<u16>,
status: Option<LitOrPath<u16>>,
#[darling(default)]
content_type: Option<String>,
#[darling(default, multiple, rename = "header")]
Expand Down Expand Up @@ -218,7 +218,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
// #[oai(status = 200)]
// Item(media)
let media_ty = &values[0].ty;
let status = get_status(variant.ident.span(), variant.status)?;
let status = get_status(variant.ident.span(), &variant.status)?;
let (update_response_content_type, update_meta_content_type) = update_content_type(
&crate_name,
variant.content_type.as_deref(),
Expand Down Expand Up @@ -257,7 +257,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
0 => {
// #[oai(status = 200)]
// Item
let status = get_status(variant.ident.span(), variant.status)?;
let status = get_status(variant.ident.span(), &variant.status)?;
let item = if !headers.is_empty() {
quote!(#ident::#item_ident(#(#match_headers),*))
} else {
Expand Down Expand Up @@ -362,16 +362,23 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
Ok(expanded)
}

fn get_status(span: Span, status: Option<u16>) -> GeneratorResult<TokenStream> {
let status = status.ok_or_else(|| Error::new(span, "Missing status attribute"))?;
if !(100..1000).contains(&status) {
return Err(Error::new(
span,
"Invalid status code, it must be greater or equal to 100 and less than 1000.",
)
.into());
fn get_status(span: Span, status: &Option<LitOrPath<u16>>) -> GeneratorResult<TokenStream> {
let status = status
.as_ref()
.ok_or_else(|| Error::new(span, "Missing status attribute"))?;
match status {
LitOrPath::Lit(status) => {
if !(100..1000).contains(status) {
return Err(Error::new(
span,
"Invalid status code, it must be greater or equal to 100 and less than 1000.",
)
.into());
}
Ok(quote!(#status))
}
LitOrPath::Path(ident) => Ok(quote!(#ident)),
}
Ok(quote!(#status))
}

fn parse_fields(
Expand Down
1 change: 1 addition & 0 deletions poem-openapi-derive/src/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
}

let schema = #crate_name::registry::MetaSchema {
description: #description,
all_of: ::std::vec![
#crate_name::registry::MetaSchemaRef::Inline(::std::boxed::Box::new(#crate_name::registry::MetaSchema {
required: #required,
Expand Down
7 changes: 7 additions & 0 deletions poem-openapi/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

#[5.1.5] 2025-01-04

- Add description to Union descriminator object schema [#921](https://github.com/poem-web/poem/pull/921)
- make Json from poem-openapi derive Default because Json from poem does [#938](https://github.com/poem-web/poem/pull/938)
- Pass `ParsePayload<T>::IS_REQUIRED` to `T` instead of defaulting to `true` [#932](https://github.com/poem-web/poem/pull/932)
- allow path in status for ApiResponse [#937](https://github.com/poem-web/poem/pull/937)

#[5.1.4] 2024-11-25

- Assign the description to the request object in OpenAPI [#886](https://github.com/poem-web/poem/pull/886)
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "poem-openapi"
version = "5.1.4"
version = "5.1.5"
authors.workspace = true
edition.workspace = true
license.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/base64_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<T: Send> Payload for Base64<T> {
&& (content_type.subtype() == "plain"
|| content_type
.suffix()
.map_or(false, |v| v == "plain")))
.is_some_and(|v| v == "plain")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl<T: Send> Payload for Binary<T> {
&& (content_type.subtype() == "octet-stream"
|| content_type
.suffix()
.map_or(false, |v| v == "octet-stream")))
.is_some_and(|v| v == "octet-stream")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/form.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl<T: Type> Payload for Form<T> {
&& (content_type.subtype() == "x-www-form-urlencoded"
|| content_type
.suffix()
.map_or(false, |v| v == "x-www-form-urlencoded")))
.is_some_and(|v| v == "x-www-form-urlencoded")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/html.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<T: Send> Payload for Html<T> {
&& (content_type.subtype() == "html"
|| content_type
.suffix()
.map_or(false, |v| v == "html")))
.is_some_and(|v| v == "html")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
6 changes: 3 additions & 3 deletions poem-openapi/src/payload/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::{
};

/// A JSON payload.
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Json<T>(pub T);

impl<T> Deref for Json<T> {
Expand All @@ -37,7 +37,7 @@ impl<T: Type> Payload for Json<T> {
&& (content_type.subtype() == "json"
|| content_type
.suffix()
.map_or(false, |v| v == "json")))
.is_some_and(|v| v == "json")))
}

fn schema_ref() -> MetaSchemaRef {
Expand All @@ -51,7 +51,7 @@ impl<T: Type> Payload for Json<T> {
}

impl<T: ParseFromJSON> ParsePayload for Json<T> {
const IS_REQUIRED: bool = true;
const IS_REQUIRED: bool = T::IS_REQUIRED;

async fn from_request(request: &Request, body: &mut RequestBody) -> Result<Self> {
let data = Vec::<u8>::from_request(request, body).await?;
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/plain_text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ impl<T: Send> Payload for PlainText<T> {
&& (content_type.subtype() == "plain"
|| content_type
.suffix()
.map_or(false, |v| v == "plain")))
.is_some_and(|v| v == "plain")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/src/payload/xml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ impl<T: Type> Payload for Xml<T> {
&& (content_type.subtype() == "xml"
|| content_type
.suffix()
.map_or(false, |v| v == "xml")))
.is_some_and(|v| v == "xml")))
}

fn schema_ref() -> MetaSchemaRef {
Expand Down
Loading

0 comments on commit 4537234

Please sign in to comment.