Skip to content

Commit

Permalink
openapi: when Union uses discriminator, if the members is not an `O…
Browse files Browse the repository at this point in the history
…bject`, an error will be reported at compile time. #755
  • Loading branch information
sunli829 committed Mar 24, 2024
1 parent 0279506 commit 869d7c0
Show file tree
Hide file tree
Showing 8 changed files with 13 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ base64 = "0.21.0"
serde_urlencoded = "0.7.1"
indexmap = "2.0.0"
reqwest = { version = "0.11.23", default-features = false }
darling = "0.20.8"
static_assertions = "1.1.0"

# rustls, update together
rustls = "0.22.0"
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ categories = ["network-programming", "asynchronous"]
proc-macro = true

[dependencies]
darling = "0.20.1"
darling.workspace = true
proc-macro-crate.workspace = true
proc-macro2.workspace = true
quote.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions poem-openapi-derive/src/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,8 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
}
}

impl #impl_generics #crate_name::types::IsObjectType for #ident #ty_generics #where_clause {}

impl #impl_generics #crate_name::types::ParseFromJSON for #ident #ty_generics #where_clause {
fn parse_from_json(value: ::std::option::Option<#crate_name::__private::serde_json::Value>) -> ::std::result::Result<Self, #crate_name::types::ParseError<Self>> {
let value = value.unwrap_or_default();
Expand Down
2 changes: 2 additions & 0 deletions poem-openapi-derive/src/union.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {

if let Some(discriminator_name) = &args.discriminator_name {
create_schemas.push(quote! {
#crate_name::__private::static_assertions::assert_impl_all!(#object_ty: #crate_name::types::IsObjectType);
let schema = #crate_name::registry::MetaSchema {
all_of: ::std::vec![
#crate_name::registry::MetaSchemaRef::Inline(::std::boxed::Box::new(#crate_name::registry::MetaSchema {
Expand Down Expand Up @@ -268,6 +269,7 @@ pub(crate) fn generate(args: DeriveInput) -> GeneratorResult<TokenStream> {
}

fn register(registry: &mut #crate_name::registry::Registry) {
use ::std::marker::Sized;
registry.create_schema::<Self, _>(<Self as #crate_name::types::Type>::name().into_owned(), |registry| {
#(<#types as #crate_name::types::Type>::register(registry);)*
#(#create_schemas)*
Expand Down
1 change: 1 addition & 0 deletions poem-openapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ thiserror.workspace = true
bytes.workspace = true
futures-util.workspace = true
indexmap.workspace = true
static_assertions.workspace = true

# Non-feature optional dependencies
email_address = { version = "0.2.1", optional = true }
Expand Down
1 change: 1 addition & 0 deletions poem-openapi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ pub mod __private {
pub use poem;
pub use serde;
pub use serde_json;
pub use static_assertions;

pub use crate::{auth::CheckerReturn, base::UrlQuery, path_util::join_path};
}
3 changes: 3 additions & 0 deletions poem-openapi/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ pub trait Type: Send + Sync {
}
}

/// Represents a object type.
pub trait IsObjectType: Type {}

/// Represents a type that can parsing from JSON.
pub trait ParseFromJSON: Sized + Type {
/// Parse from [`serde_json::Value`].
Expand Down
2 changes: 1 addition & 1 deletion poem-openapi/tests/security_scheme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use poem::{
http::{header, StatusCode},
test::TestClient,
web::{cookie::Cookie, headers},
Error, Request,
Request,
};
use poem_openapi::{
auth::{ApiKey, Basic, Bearer},
Expand Down

0 comments on commit 869d7c0

Please sign in to comment.