Skip to main content

kynos_openapi/
lib.rs

1//! The OpenAPI 3.1 and 3.2 document model.
2//!
3//! This crate is the data model Kynos emits into, and is deliberately free of
4//! any runtime dependency: no `tokio`, no `hyper`. It can be used on its own to
5//! build, serialize, or validate an OpenAPI description.
6//!
7//! # Specification versions
8//!
9//! `openapi31` is the baseline and is enabled by default. `openapi32` adds the
10//! fields introduced by OpenAPI 3.2.0 as a strict superset.
11//!
12//! Fields introduced by 3.2 are `#[cfg]`-gated rather than runtime-optional, so
13//! a build without `openapi32` cannot construct a document it would be unable
14//! to describe. Where a program needs a 3.1 document from a build that has
15//! `openapi32` enabled — Cargo unifies features across a dependency graph, so
16//! this is not always the program's own choice — use [`Document::emit`], which
17//! fails with the list of 3.2-only constructs that block the downgrade rather
18//! than silently emitting an invalid description.
19//!
20//! # A note on the JSON Schema dialect
21//!
22//! OpenAPI 3.2 did *not* mint a new JSON Schema dialect. Both 3.1 and 3.2 use
23//! `https://spec.openapis.org/oas/3.1/dialect/base`, exposed here as
24//! [`model::schema::dialect::OAS_DIALECT`]. It is not versioned by feature
25//! flag.
26//!
27//! # Example
28//!
29//! ```
30//! use kynos_openapi::{Document, Info, SpecVersion};
31//!
32//! let doc = Document::new(SpecVersion::V3_1, Info::new("Orders", "1.0.0"));
33//! let json = doc.to_json().expect("serializable");
34//! assert!(json.contains("\"openapi\""));
35//! ```
36
37// `openapi31` is the baseline object model, not an optional extra: without it
38// there is nothing to build a description out of. `openapi32` implies it, so
39// this fires only when a caller disables default features and asks for neither.
40#[cfg(not(feature = "openapi31"))]
41compile_error!(
42    "kynos-openapi requires the `openapi31` feature. OpenAPI 3.1 is the baseline object model; \
43     enable `openapi31`, or `openapi32`, which implies it."
44);
45
46pub mod annotation;
47pub mod emit;
48pub mod model;
49pub mod validate;
50
51// The curated crate-root facade. Every item below has exactly one canonical
52// path inside `model` or `validate`; these shortcuts exist so that the common
53// names stay one import away despite the module tree being deep.
54pub use crate::{
55    annotation::{MalformedAnnotation, Opaque, OpaqueReason, OpaqueRoute},
56    model::{
57        body::{RequestBody, encoding::Encoding, media_type::MediaType},
58        callback::Callback,
59        components::{ComponentName, Components},
60        document::{Document, SpecVersion},
61        example::{Example, ExampleValue, Examples},
62        extensions::Extensions,
63        external_docs::ExternalDocumentation,
64        info::{Contact, Info, License},
65        link::{Link, LinkTarget},
66        parameter::{
67            Parameter, ParameterIn, ParameterShape,
68            header::{Header, HeaderShape},
69            style::{EncodingStyle, HeaderStyle, Style},
70        },
71        paths::{
72            Paths, item::PathItem, method::Method, operation::Operation, template::PathTemplate,
73        },
74        reference::{Ref, RefOr},
75        response::{Response, Responses, status::StatusPattern},
76        schema::{Schema, discriminator::Discriminator, object::SchemaObject, xml::Xml},
77        security::{
78            SecurityScheme,
79            oauth::{OAuthFlow, OAuthFlows},
80            requirement::SecurityRequirement,
81        },
82        server::{Server, ServerVariable},
83        tag::Tag,
84    },
85    validate::violation::{Severity, SpecError, Violation},
86};
87
88/// The ordered map used throughout the model.
89///
90/// Field order in an OpenAPI description is not semantically meaningful, but
91/// preserving insertion order makes emitted documents byte-stable across runs,
92/// which in turn makes them reviewable in version control.
93pub type Map<V> = indexmap::IndexMap<String, V>;