Skip to content

Commit

Permalink
Fix nullable ref schema inline (#510)
Browse files Browse the repository at this point in the history
Fix nullable ref schema for inline fields in ToSchema. Also revert back
breaking change in utoipa/schema.rs since it is not needed to nullable
to work.
  • Loading branch information
juhaku authored Mar 10, 2023
1 parent 1fbe015 commit 2e501eb
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 76 deletions.
4 changes: 2 additions & 2 deletions utoipa-gen/src/component/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1645,11 +1645,11 @@ impl ToTokens for SchemaProperty<'_> {
let type_path = &**type_tree.path.as_ref().unwrap();
if is_inline {
nullable
.map(|_| {
.map(|nullable| {
quote_spanned! {type_path.span()=>
utoipa::openapi::schema::AllOfBuilder::new()
#nullable
.item(<#type_path as utoipa::ToSchema>::schema().1)
.item(utoipa::openapi::schema::Object::nullable())
}
})
.unwrap_or_else(|| {
Expand Down
8 changes: 2 additions & 6 deletions utoipa-gen/tests/schema_derive_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ fn derive_struct_with_inline() {
"type": "object"
},
"foo2": {
"nullable": true,
"allOf": [
{
"properties": {
Expand All @@ -699,13 +700,11 @@ fn derive_struct_with_inline() {
"name"
],
"type": "object"
},
{
"nullable": true,
}
]
},
"foo3": {
"nullable": true,
"allOf": [
{
"properties": {
Expand All @@ -717,9 +716,6 @@ fn derive_struct_with_inline() {
"name"
],
"type": "object"
},
{
"nullable": true,
}
]
},
Expand Down
75 changes: 7 additions & 68 deletions utoipa/src/openapi/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ pub enum Schema {
/// Defines array schema from another schema. Typically used with
/// [`Schema::Object`]. Slice and Vec types are translated to [`Schema::Array`] types.
Array(Array),
/// Defines object schema. Object is either `object` holding **properties** which are other [`Schema`]s
/// or can be a field within the [`Object`].
Object(Object),
/// Creates a _OneOf_ type [composite Object][composite] schema. This schema
/// is used to map multiple schemas together where API endpoint could return any of them.
/// [`Schema::OneOf`] is created form complex enum where enum holds other than unit types.
Expand All @@ -256,9 +259,6 @@ pub enum Schema {
///
/// [composite]: https://spec.openapis.org/oas/latest.html#components-object
AllOf(AllOf),
/// Defines object schema. Object is either `object` holding **properties** which are other [`Schema`]s
/// or can be a field within the [`Object`].
Object(Object),
}

impl Default for Schema {
Expand Down Expand Up @@ -551,15 +551,14 @@ builder! {
///
/// [schema]: https://spec.openapis.org/oas/latest.html#schema-object
#[non_exhaustive]
#[derive(Serialize, Deserialize, Clone, PartialEq)]
#[derive(Serialize, Deserialize, Default, Clone, PartialEq)]
#[cfg_attr(feature = "debug", derive(Debug))]
#[serde(rename_all = "camelCase")]
pub struct Object {
/// Type of [`Object`] e.g. [`SchemaType::Object`] for `object` and [`SchemaType::String`] for
/// `string` types.
#[serde(rename = "type")]
#[serde(skip_serializing_if = "Option::is_none")]
pub schema_type: Option<SchemaType>,
pub schema_type: SchemaType,

/// Changes the [`Object`] title.
#[serde(skip_serializing_if = "Option::is_none")]
Expand Down Expand Up @@ -679,37 +678,6 @@ fn is_false(value: &bool) -> bool {
!*value
}

impl Default for Object {
fn default() -> Self {
Self {
schema_type: Some(SchemaType::Object),
title: Default::default(),
format: Default::default(),
description: Default::default(),
default: Default::default(),
enum_values: Default::default(),
required: Default::default(),
properties: Default::default(),
additional_properties: Default::default(),
deprecated: Default::default(),
example: Default::default(),
write_only: Default::default(),
read_only: Default::default(),
xml: Default::default(),
nullable: Default::default(),
multiple_of: Default::default(),
maximum: Default::default(),
minimum: Default::default(),
exclusive_maximum: Default::default(),
exclusive_minimum: Default::default(),
max_length: Default::default(),
min_length: Default::default(),
pattern: Default::default(),
max_properties: Default::default(),
min_properties: Default::default(),
}
}
}

impl Object {
/// Initialize a new [`Object`] with default [`SchemaType`]. This effectively same as calling
Expand All @@ -729,36 +697,7 @@ impl Object {
/// ```
pub fn with_type(schema_type: SchemaType) -> Self {
Self {
schema_type: Some(schema_type),
..Default::default()
}
}

/// Initialize new empty nullable [`Object`].
///
/// This is useful in combination of [`AllOf`] to create nullable type from another type.
///
/// # Examples
///
/// Create nullable type with name.
/// ```rust
/// # use utoipa::openapi::schema::{AllOfBuilder, ObjectBuilder, Object, SchemaType};
/// let nullable_type = AllOfBuilder::new()
/// .item(ObjectBuilder::new().property("name", Object::with_type(SchemaType::String)))
/// .item(Object::nullable()).build();
/// # assert_json_diff::assert_json_eq!(nullable_type, serde_json::json!({
/// # "allOf": [
/// # {"properties": {
/// # "name": { "type": "string"},
/// # }, "type": "object"},
/// # {"nullable": true }
/// # ]
/// # }))
/// ```
pub fn nullable() -> Self {
Self {
schema_type: None,
nullable: true,
schema_type,
..Default::default()
}
}
Expand All @@ -775,7 +714,7 @@ impl ToArray for Object {}
impl ObjectBuilder {
/// Add or change type of the object e.g [`SchemaType::String`].
pub fn schema_type(mut self, schema_type: SchemaType) -> Self {
set_value!(self schema_type Some(schema_type))
set_value!(self schema_type schema_type)
}

/// Add or change additional format for detailing the schema type.
Expand Down

0 comments on commit 2e501eb

Please sign in to comment.