#[derive(AsSchema)]
{
// Attributes available to this derive:
#[schema]
}
Expand description
Derive macro for AsSchema trait.
§Implementation Notes
§1. Description Concatenation
#[derive(AsSchema)]
#[schema(description = "Top description ")]
#[schema(description = "continuation")]
struct Type {
#[schema(description = "field description ")]
#[schema(description = "continuation")]
field: String,
}
assert_eq!(
Type::as_schema(),
Schema {
description: "Top description continuation".to_owned(),
r#type: SchemaType::Object as i32,
properties: [(
"field".to_owned(),
Schema {
description: "field description continuation".to_owned(),
..String::as_schema()
}
)].into(),
required: ["field".to_owned()].into(),
..Default::default()
}
)§1. Custom Schema Generation
as_schema - Direct schema override:
#[derive(AsSchema)]
struct Timestamp {
#[schema(as_schema = "datetime_schema")]
millis: i64,
}
/// Simple schema function signature
fn datetime_schema() -> Schema {
...
}as_schema_generic - Handle generic types:
use std::marker::PhantomData;
struct Wrapper<T> {
inner: T,
}
#[derive(AsSchema)]
struct Data {
#[schema(as_schema_generic = "wrapper_schema")]
field: Wrapper<String>,
}
fn wrapper_schema<T: AsSchema>() -> (Schema, PhantomData<Wrapper<T>>) {
...
}
// NOTE: For enums with struct data:
#[derive(AsSchema)]
enum E {
#[schema(as_schema_generic = "variant1_schema")]
Variant {a: String, b: String},
}
// Notice that the return is a tuple
fn variant1_schema() -> (Schema, PhantomData<(String, String)>) {
...
}
// Although it is more ideal to use ordinary as_schema in this example.§2. Name Transformation
rename_all vs rename_all_with:
#[derive(AsSchema)]
#[schema(rename_all = "snake_case")] // Built-in conventions
struct SimpleCase { /* ... */ }
#[derive(AsSchema)]
#[schema(rename_all_with = "reverse_names")] // Custom function
struct CustomCase {
field_one: String, // Becomes "eno_dleif"
}
/// Must be deterministic pure function
fn reverse_names(s: &str) -> String {
s.chars().rev().collect()
}§3. Type Handling Nuances
Tuples:
struct SimpleTuple(u32); // → Transparent wrapper
struct MixedTuple(u32, String); // → Array with unspecified items
struct UniformTuple(u32, u32); // → Array with item(u32 here) schemaFor more control, use AsSchemaWithSerde.
Enums:
Data-less enumsbecome string enums
#[derive(AsSchema)]
enum Status {
Active,
Inactive
}
assert_eq!(
Status::as_schema(),
Schema {
r#type: SchemaType::String as i32,
format: "enum".to_owned(),
r#enum: ["Active".to_owned(), "Inactive".to_owned()].into(),
..Default::default()
}
)Data-containing enumsbecome structural objects with all fields unrequired by default. Return matches serde deserialization.
#[derive(AsSchema)]
enum Response {
Success { data: String },
Error(String),
}
assert_eq!(
Response::as_schema(),
Schema {
r#type: SchemaType::Object as i32,
properties: [
(
"Success".to_owned(),
Schema {
r#type: SchemaType::Object as i32,
properties: [("data".to_owned(), String::as_schema())].into(),
required: ["data".to_owned()].into(),
..Default::default()
}
),
("Error".to_owned(), String::as_schema())
].into(),
required: vec![], // None is required by default
..Default::default()
}
)