From c19d0ce000a37b8f852644f87b0fc48e37b155b5 Mon Sep 17 00:00:00 2001 From: kanarus Date: Mon, 11 Aug 2025 06:17:18 +0900 Subject: [PATCH] docs(openapi): documentation for `Schema` trait --- ohkami_openapi/src/lib.rs | 91 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/ohkami_openapi/src/lib.rs b/ohkami_openapi/src/lib.rs index 0bcbe6eb2..5fd5ce9f5 100644 --- a/ohkami_openapi/src/lib.rs +++ b/ohkami_openapi/src/lib.rs @@ -28,38 +28,129 @@ pub enum Inbound { Security { scheme: SecurityScheme, scopes: &'static [&'static str] }, } +/// handle the `schema` as a component schema named `name`. +/// This is useful for reusing schemas in the OpenAPI document. pub fn component(name: &'static str, schema: schema::Schema) -> schema::Schema { schema::Schema::component(name, schema) } +/// `type: string` pub fn string() -> schema::Schema { schema::Schema::string() } +/// `type: number` pub fn number() -> schema::Schema { schema::Schema::number() } +/// `type: integer` pub fn integer() -> schema::Schema { schema::Schema::integer() } +/// `type: boolean` pub fn bool() -> schema::Schema { schema::Schema::bool() } +/// ```txt +/// type: array +/// items: +/// type: ###`items`'s schema### +/// ``` pub fn array(items: impl Into) -> schema::Schema { schema::Schema::array(items) } +/// `type: object` pub fn object() -> schema::Schema { schema::Schema::object() } +/// `anyOf: [...{schemas}]` pub fn any_of(schemas: impl schema::SchemaList) -> schema::Schema { schema::Schema::any_of(schemas) } +/// `allOf: [...{schemas}]` pub fn all_of(schemas: impl schema::SchemaList) -> schema::Schema { schema::Schema::all_of(schemas) } +/// `oneOf: [...{schemas}]` pub fn one_of(schemas: impl schema::SchemaList) -> schema::Schema { schema::Schema::one_of(schemas) } +/// # OpenAPI Schema trait +/// +/// ## Required +/// +/// - `schema() -> impl Into` +/// - this `impl Into` mostly means `schema::Schema<{something}>`. +/// +/// ## Implementation Notes +/// +/// Generally, you can implement this trait for your types by `#[derive(Schema)]`. +/// See it's documentation for more details. +/// +/// But of course, you can implement it manually if you want to. +/// In that case, start from **base schemas**: +/// +/// - [`string()`](fn@string) +/// - [`number()`](fn@number) +/// - [`integer()`](fn@integer) +/// - [`bool()`](fn@bool) +/// - [`array({items})`](fn@array) +/// - [`object()`](fn@object) +/// - [`any_of({schemas})`](fn@any_of) +/// - [`all_of({schemas})`](fn@all_of) +/// - [`one_of({schemas})`](fn@one_of) +/// +/// and, [`component({name}, {schema})`](fn@component) if you want to name and reuse +/// the schema in the OpenAPI document. +/// +/// ## Example +/// +/// ```rust,ignore +/// use ohkami::openapi; +/// +/// #[derive(openapi::Schema)] +/// struct MySchema { +/// pub id: u32, +/// pub name: String, +/// pub age: Option, +/// } +/// /* equivalent to: */ +/// impl openapi::Schema for MySchema { +/// fn schema() -> impl Into { +/// openapi::object() +/// .property("id", openapi::integer().format("uint32")) +/// .property("name", openapi::string()) +/// .optional("age", openapi::integer().format("uint8")) +/// } +/// } +/// +/// #[derive(openapi::Schema)] +/// #[openapi(component)] +/// struct MyComponentSchema { +/// pub id: u32, +/// pub name: String, +/// pub age: Option, +/// } +/// /* equivalent to: */ +/// impl openapi::Schema for MyComponentSchema { +/// fn schema() -> impl Into { +/// openapi::component("MyComponentSchema", openapi::object() +/// .property("id", openapi::integer().format("uint32")) +/// .property("name", openapi::string()) +/// .optional("age", openapi::integer().format("uint8")) +/// ) +/// } +/// } +/// ``` +/// +/// ## Default Implementations +/// +/// - `str`, `String` +/// - `u8`, `u16`, `u32`, `u64`, `usize` +/// - `i8`, `i16`, `i32`, `i64`, `isize` +/// - `f32`, `f64` +/// - `uuid::Uuid` +/// - `Vec`, `[S]`, `[S; N]`, `Cow<'_, S>`, `Arc`, `&S` where `S: Schema` pub trait Schema { fn schema() -> impl Into; }