utoipa
utoipa copied to clipboard
Serde flattened enum as top level fields (not `oneOf`)
When using an enum as a struct field with a serde flattened
annotation, I would like the enum fields pulled up to the top level instead of being nested under a OneOf
definition as three distinct items. My example enum has a three definitions, all with a common appData
field and one with an optional appDataHash
.
What I would like:
appData:
description: |
This field comes in two forms for backward compatibility. The hash form will eventually
stop being accepted.
anyOf:
- title: Full App Data
allOf:
- $ref: "#/components/schemas/AppData"
description:
type: string
- $ref: "#/components/schemas/AppDataHash"
appDataHash:
description:
allOf:
- $ref: "#/components/schemas/AppDataHash"
nullable: true
What I get instead is these different versions nested under a oneOf
parent:
OrderCreation:
allOf:
- oneOf:
- type: object
description: Hash is inferred from full app data and validated against expectation.
required:
- appData
- appDataHash
properties:
appData:
type: string
appDataHash:
type: string
- type: object
description: Backward compatible app data hash.
required:
- appData
properties:
appData:
type: string
- type: object
description: Hash is inferred from full app data.
required:
- appData
properties:
appData:
type: string
description: The string encoding of a JSON object representing some `appData`.
- type: object
required:
- sellToken
- buyToken
properties:
sellToken:
type: string
description: Address of token sold.
example: 0x6810e776880c02933d47db1b9fc05908e5386b96
buyToken:
type: string
description: Address of token bought.
example: 0x6810e776880c02933d47db1b9fc05908e5386b96
description: An order as provided to the POST order endpoint.
Code below:
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, ToSchema)]
#[serde(untagged)]
/// The string encoding of a JSON object representing some `appData`.
pub enum OrderCreationAppData {
/// Hash is inferred from full app data and validated against expectation.
Both {
#[serde(rename = "appData")]
full: String,
#[serde(rename = "appDataHash")]
expected: String,
},
/// Backward compatible app data hash.
Hash {
#[serde(rename = "appData")]
hash: String,
},
/// Hash is inferred from full app data.
Full {
#[serde(rename = "appData")]
full: String,
},
}
impl Default for OrderCreationAppData {
fn default() -> Self {
Self::Hash {
hash: Default::default(),
}
}
}
/// An order as provided to the POST order endpoint.
#[serde_as]
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct OrderCreation {
/// Address of token sold.
#[schema(value_type = String, example = "0x6810e776880c02933d47db1b9fc05908e5386b96")]
pub sell_token: String,
/// Address of token bought.
#[schema(value_type = String, example = "0x6810e776880c02933d47db1b9fc05908e5386b96")]
pub buy_token: String,
/// The string encoding of a JSON object representing some `appData`.
#[serde(flatten)]
#[schema(inline)]
pub app_data: OrderCreationAppData,
}