use domainstack_schema::{OpenApiBuilder, Schema, ToSchema};
#[allow(dead_code)]
struct User {
email: String,
age: u8,
name: String,
status: String,
}
impl ToSchema for User {
fn schema_name() -> &'static str {
"User"
}
fn schema() -> Schema {
Schema::object()
.description("User account")
.property(
"email",
Schema::string()
.format("email")
.description("User email address"),
)
.property(
"age",
Schema::integer()
.minimum(18)
.maximum(120)
.description("User age (18-120)"),
)
.property(
"name",
Schema::string()
.min_length(3)
.max_length(50)
.description("User full name"),
)
.property(
"status",
Schema::string()
.enum_values(&["active", "pending", "inactive"])
.description("User account status"),
)
.required(&["email", "age", "name", "status"])
}
}
#[allow(dead_code)]
struct Address {
street: String,
zip_code: String,
city: String,
}
impl ToSchema for Address {
fn schema_name() -> &'static str {
"Address"
}
fn schema() -> Schema {
Schema::object()
.description("Physical address")
.property(
"street",
Schema::string()
.min_length(1)
.max_length(100)
.description("Street address"),
)
.property(
"zipCode",
Schema::string()
.min_length(5)
.max_length(5)
.pattern("^[0-9]{5}$")
.description("5-digit ZIP code"),
)
.property(
"city",
Schema::string()
.min_length(2)
.max_length(50)
.description("City name"),
)
.required(&["street", "zipCode", "city"])
}
}
#[allow(dead_code)]
struct Team {
name: String,
members: Vec<String>, }
impl ToSchema for Team {
fn schema_name() -> &'static str {
"Team"
}
fn schema() -> Schema {
Schema::object()
.description("Team of users")
.property(
"name",
Schema::string()
.min_length(1)
.max_length(50)
.description("Team name"),
)
.property(
"members",
Schema::array(Schema::reference("User"))
.min_items(1)
.max_items(10)
.description("Team members (1-10 users)"),
)
.required(&["name", "members"])
}
}
fn main() {
let spec = OpenApiBuilder::new("User Management API", "1.0.0")
.description("API for managing users, addresses, and teams with validation")
.register::<User>()
.register::<Address>()
.register::<Team>()
.build();
let json = spec.to_json().expect("Failed to serialize to JSON");
println!("{}", json);
println!("\n=== Schema Generation Complete ===");
println!("Registered schemas:");
println!(" - User (with email, age, name, status)");
println!(" - Address (with street, zip code, city)");
println!(" - Team (with name and members array)");
println!("\nValidation constraints mapped to OpenAPI:");
println!(" [ok] email → format: email");
println!(" [ok] range(min, max) → minimum, maximum");
println!(" [ok] length(min, max) → minLength, maxLength");
println!(" [ok] one_of → enum");
println!(" [ok] min_items, max_items → minItems, maxItems");
println!(" [ok] numeric_string → pattern: ^[0-9]+$");
}