Skip to content

Commit

Permalink
Add extensions for schemas (#983)
Browse files Browse the repository at this point in the history
  • Loading branch information
heat1q authored Aug 5, 2024
1 parent 2088259 commit b941d64
Showing 1 changed file with 112 additions and 1 deletion.
113 changes: 112 additions & 1 deletion utoipa/src/openapi/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! used to define field properties, enum values, array or object types.
//!
//! [schema]: https://spec.openapis.org/oas/latest.html#schema-object
use std::collections::BTreeMap;
use std::collections::{BTreeMap, HashMap};

use serde::{Deserialize, Serialize};
use serde_json::Value;
Expand Down Expand Up @@ -350,6 +350,10 @@ builder! {
/// Set `true` to allow `"null"` to be used as value for given type.
#[serde(default, skip_serializing_if = "is_false")]
pub nullable: bool,

/// Optional extensions `x-something`.
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
}

Expand Down Expand Up @@ -421,6 +425,11 @@ impl OneOfBuilder {
set_value!(self nullable nullable)
}

/// Add openapi extensions (`x-something`) for [`OneOf`].
pub fn extensions(mut self, extensions: Option<HashMap<String, serde_json::Value>>) -> Self {
set_value!(self extensions extensions)
}

to_array_builder!();
}

Expand Down Expand Up @@ -478,6 +487,10 @@ builder! {
/// Set `true` to allow `"null"` to be used as value for given type.
#[serde(default, skip_serializing_if = "is_false")]
pub nullable: bool,

/// Optional extensions `x-something`.
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
}

Expand Down Expand Up @@ -549,6 +562,11 @@ impl AllOfBuilder {
set_value!(self nullable nullable)
}

/// Add openapi extensions (`x-something`) for [`AllOf`].
pub fn extensions(mut self, extensions: Option<HashMap<String, serde_json::Value>>) -> Self {
set_value!(self extensions extensions)
}

to_array_builder!();
}

Expand Down Expand Up @@ -602,6 +620,10 @@ builder! {
/// Set `true` to allow `"null"` to be used as value for given type.
#[serde(default, skip_serializing_if = "is_false")]
pub nullable: bool,

/// Optional extensions `x-something`.
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
}

Expand Down Expand Up @@ -668,6 +690,11 @@ impl AnyOfBuilder {
set_value!(self nullable nullable)
}

/// Add openapi extensions (`x-something`) for [`AnyOf`].
pub fn extensions(mut self, extensions: Option<HashMap<String, serde_json::Value>>) -> Self {
set_value!(self extensions extensions)
}

to_array_builder!();
}

Expand Down Expand Up @@ -820,6 +847,10 @@ builder! {
/// `0` will have same effect as omitting the attribute.
#[serde(skip_serializing_if = "Option::is_none")]
pub min_properties: Option<usize>,

/// Optional extensions `x-something`.
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
}

Expand Down Expand Up @@ -1002,6 +1033,11 @@ impl ObjectBuilder {
set_value!(self min_properties min_properties)
}

/// Add openapi extensions (`x-something`) for [`Object`].
pub fn extensions(mut self, extensions: Option<HashMap<String, serde_json::Value>>) -> Self {
set_value!(self extensions extensions)
}

to_array_builder!();
}

Expand Down Expand Up @@ -1198,6 +1234,10 @@ builder! {
/// Set `true` to allow `"null"` to be used as value for given type.
#[serde(default, skip_serializing_if = "is_false")]
pub nullable: bool,

/// Optional extensions `x-something`.
#[serde(skip_serializing_if = "Option::is_none", flatten)]
pub extensions: Option<HashMap<String, serde_json::Value>>,
}
}

Expand All @@ -1216,6 +1256,7 @@ impl Default for Array {
min_items: Default::default(),
xml: Default::default(),
nullable: Default::default(),
extensions: Default::default(),
}
}
}
Expand Down Expand Up @@ -1294,6 +1335,11 @@ impl ArrayBuilder {
set_value!(self nullable nullable)
}

/// Add openapi extensions (`x-something`) for [`Array`].
pub fn extensions(mut self, extensions: Option<HashMap<String, serde_json::Value>>) -> Self {
set_value!(self extensions extensions)
}

to_array_builder!();
}

Expand Down Expand Up @@ -2074,4 +2120,69 @@ mod tests {
})
);
}

#[test]
fn object_with_extensions() {
let expected = json!("value");
let json_value = ObjectBuilder::new()
.extensions(Some(
[("x-some-extension".to_string(), expected.clone())].into(),
))
.build();

let value = serde_json::to_value(&json_value).unwrap();
assert_eq!(value.get("x-some-extension"), Some(&expected));
}

#[test]
fn array_with_extensions() {
let expected = json!("value");
let json_value = ArrayBuilder::new()
.extensions(Some(
[("x-some-extension".to_string(), expected.clone())].into(),
))
.build();

let value = serde_json::to_value(&json_value).unwrap();
assert_eq!(value.get("x-some-extension"), Some(&expected));
}

#[test]
fn oneof_with_extensions() {
let expected = json!("value");
let json_value = OneOfBuilder::new()
.extensions(Some(
[("x-some-extension".to_string(), expected.clone())].into(),
))
.build();

let value = serde_json::to_value(&json_value).unwrap();
assert_eq!(value.get("x-some-extension"), Some(&expected));
}

#[test]
fn allof_with_extensions() {
let expected = json!("value");
let json_value = AllOfBuilder::new()
.extensions(Some(
[("x-some-extension".to_string(), expected.clone())].into(),
))
.build();

let value = serde_json::to_value(&json_value).unwrap();
assert_eq!(value.get("x-some-extension"), Some(&expected));
}

#[test]
fn anyof_with_extensions() {
let expected = json!("value");
let json_value = AnyOfBuilder::new()
.extensions(Some(
[("x-some-extension".to_string(), expected.clone())].into(),
))
.build();

let value = serde_json::to_value(&json_value).unwrap();
assert_eq!(value.get("x-some-extension"), Some(&expected));
}
}

0 comments on commit b941d64

Please sign in to comment.