Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement serde tag property for simple enums #146

Merged
merged 20 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
d1659b7
Implement serde `tag` property for simple enums
kellpossible May 27, 2022
ba14399
Make simple enum serde tag handling more functional
kellpossible May 27, 2022
00bc262
Reformat and reorganise serde tag tests
kellpossible May 27, 2022
bb4a6b1
Documentation for `rename()`.
kellpossible May 27, 2022
c74c3b6
Documentation for `rename_field()` and `rename_variant()`
kellpossible May 27, 2022
4759362
Rename some component derive tests, add new tests for variant renames
kellpossible May 28, 2022
3af0e8c
Simplify ComplexEnum Component derive
kellpossible May 28, 2022
ccfd02c
Refactor SimpleEnum ToTokens
kellpossible May 28, 2022
57ab646
Documentation for SimpleEnum
kellpossible May 28, 2022
fe96b97
Rename variable in ComplexEnum implementation
kellpossible May 28, 2022
c29bd9a
Rename variable in ComplexEnum implementation
kellpossible May 28, 2022
ff1999e
Support internally tagged enum representation
kellpossible May 28, 2022
24886c6
Remove todo, it's documented in the PR now
kellpossible May 28, 2022
ced1497
Remove unnecessary Serde enum
kellpossible May 28, 2022
7c7a911
Remove unecessary Serde enum
kellpossible May 29, 2022
9fd6759
Reformat code in schema.rs
kellpossible May 29, 2022
824041b
Remove an unecessary test from component_derive_tests.rs
kellpossible May 29, 2022
4dce7e9
Refactored SerdeContainer parse_ident method for PR
kellpossible Jun 15, 2022
2c13eb7
Remove useless tokens.extend()
kellpossible Jun 15, 2022
f3eba2b
Remove unnecessary mut references from serde rename attribute
kellpossible Jun 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ serde_yaml = { version = "0.8", optional = true }
utoipa-gen = { version = "1.0.2", path = "./utoipa-gen" }

[dev-dependencies]
assert-json-diff = "2"
actix-web = { version = "4" }
paste = "1"
chrono = { version = "0.4", features = ["serde"] }
Expand Down
350 changes: 335 additions & 15 deletions tests/component_derive_test.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#![cfg(feature = "serde_json")]
use std::{borrow::Cow, cell::RefCell, collections::HashMap, marker::PhantomData, vec};

use assert_json_diff::assert_json_eq;
#[cfg(any(feature = "chrono", feature = "chrono_with_format"))]
use chrono::{Date, DateTime, Duration, Utc};

use serde::Serialize;
use serde_json::Value;
use serde_json::{json, Value};
use utoipa::{Component, OpenApi};

use crate::common::get_json_path;
Expand Down Expand Up @@ -507,9 +508,100 @@ fn derive_with_box_and_refcell() {
}

#[test]
fn derive_complex_enum_with_named_and_unnamed_fields() {
struct Foo;
let complex_enum = api_doc! {
fn derive_simple_enum() {
let value: Value = api_doc! {
#[derive(Serialize)]
enum Bar {
A,
B,
C,
}
};

assert_json_eq!(
value,
json!({
"enum": [
"A",
"B",
"C",
],
"type": "string",
})
);
}

#[test]
fn derive_simple_enum_serde_tag() {
let value: Value = api_doc! {
#[derive(Serialize)]
#[serde(tag = "tag")]
enum Bar {
A,
B,
C,
}
};

assert_json_eq!(
value,
json!({
"oneOf": [
{
"type": "object",
"properties": {
"tag": {
"type": "string",
"enum": [
"A",
],
},
},
"required": [
"tag",
],
},
{
"type": "object",
"properties": {
"tag": {
"type": "string",
"enum": [
"B",
],
},
},
"required": [
"tag",
],
},
{
"type": "object",
"properties": {
"tag": {
"type": "string",
"enum": [
"C",
],
},
},
"required": [
"tag",
],
},
],
})
);
}

/// Derive a complex enum with named and unnamed fields.
#[test]
fn derive_complex_enum() {
#[derive(Serialize)]
struct Foo(String);

let value: Value = api_doc! {
#[derive(Serialize)]
enum Bar {
UnitValue,
NamedFields {
Expand All @@ -520,17 +612,245 @@ fn derive_complex_enum_with_named_and_unnamed_fields() {
}
};

common::assert_json_array_len(complex_enum.get("oneOf").unwrap(), 3);
assert_value! {complex_enum=>
"oneOf.[0].type" = r###""string""###, "Complex enum unit value type"
"oneOf.[0].enum" = r###"["UnitValue"]"###, "Complex enum unit value enum"
"oneOf.[1].type" = r###""object""###, "Complex enum named fields type"
"oneOf.[1].properties.NamedFields.type" = r###""object""###, "Complex enum named fields object type"
"oneOf.[1].properties.NamedFields.properties.id.type" = r###""string""###, "Complex enum named fields id type"
"oneOf.[1].properties.NamedFields.properties.names.type" = r###""array""###, "Complex enum named fields names type"
"oneOf.[2].type" = r###""object""###, "Complex enum unnamed fields type"
"oneOf.[2].properties.UnnamedFields.$ref" = r###""#/components/schemas/Foo""###, "Complex enum unnamed fields type"
}
assert_json_eq!(
value,
json!({
"oneOf": [
{
"type": "string",
"enum": [
"UnitValue",
],
},
{
"type": "object",
"properties": {
"NamedFields": {
"type": "object",
"properties": {
"id": {
"type": "string",
},
"names": {
"type": "array",
"items": {
"type": "string",
},
},
},
"required": [
"id",
],
},
},
},
{
"type": "object",
"properties": {
"UnnamedFields": {
"$ref": "#/components/schemas/Foo",
},
},
},
],
})
);
}

#[test]
fn derive_complex_enum_serde_rename_all() {
#[derive(Serialize)]
struct Foo(String);

let value: Value = api_doc! {
#[derive(Serialize)]
#[serde(rename_all = "snake_case")]
enum Bar {
UnitValue,
NamedFields {
id: &'static str,
names: Option<Vec<String>>
},
UnnamedFields(Foo),
}
};

assert_json_eq!(
value,
json!({
"oneOf": [
{
"type": "string",
"enum": [
"unit_value",
],
},
{
"type": "object",
"properties": {
"named_fields": {
"type": "object",
"properties": {
"id": {
"type": "string",
},
"names": {
"type": "array",
"items": {
"type": "string",
},
},
},
"required": [
"id",
],
},
},
},
{
"type": "object",
"properties": {
"unnamed_fields": {
"$ref": "#/components/schemas/Foo",
},
},
},
],
})
);
}

#[test]
fn derive_complex_enum_serde_rename_variant() {
#[derive(Serialize)]
struct Foo(String);

let value: Value = api_doc! {
#[derive(Serialize)]
enum Bar {
#[serde(rename = "renamed_unit_value")]
UnitValue,
#[serde(rename = "renamed_named_fields")]
NamedFields {
#[serde(rename = "renamed_id")]
id: &'static str,
#[serde(rename = "renamed_names")]
names: Option<Vec<String>>
},
#[serde(rename = "renamed_unnamed_fields")]
UnnamedFields(Foo),
}
};

assert_json_eq!(
value,
json!({
"oneOf": [
{
"type": "string",
"enum": [
"renamed_unit_value",
],
},
{
"type": "object",
"properties": {
"renamed_named_fields": {
"type": "object",
"properties": {
"renamed_id": {
"type": "string",
},
"renamed_names": {
"type": "array",
"items": {
"type": "string",
},
},
},
"required": [
"renamed_id",
],
},
},
},
{
"type": "object",
"properties": {
"renamed_unnamed_fields": {
"$ref": "#/components/schemas/Foo",
},
},
},
],
})
);
}

/// Derive a complex enum with the serde `tag` container attribute applied for internal tagging.
/// Note that tuple fields are not supported.
#[test]
fn derive_complex_enum_serde_tag() {
#[derive(Serialize)]
struct Foo(String);

let value: Value = api_doc! {
#[derive(Serialize)]
#[serde(tag = "tag")]
enum Bar {
UnitValue,
NamedFields {
id: &'static str,
names: Option<Vec<String>>
},
}
};

assert_json_eq!(
value,
json!({
"oneOf": [
{
"type": "object",
"properties": {
"tag": {
"type": "string",
"enum": [
"UnitValue",
],
},
},
"required": [
"tag",
],
},
{
"type": "object",
"properties": {
"id": {
"type": "string",
},
"names": {
"type": "array",
"items": {
"type": "string",
},
},
"tag": {
"type": "string",
"enum": [
"NamedFields",
],
},
},
"required": [
"id",
"tag",
],
},
],
})
);
}

#[test]
Expand Down
Loading