okapi_operation/
components.rs1use okapi::{
2 openapi3::{RefOr, SchemaObject, SecurityScheme},
3 schemars::{
4 JsonSchema,
5 gen::{SchemaGenerator, SchemaSettings},
6 },
7};
8
9pub struct ComponentsBuilder {
11 components: okapi::openapi3::Components,
12 inline_subschemas: bool,
13}
14
15#[allow(clippy::derivable_impls)]
16impl Default for ComponentsBuilder {
17 fn default() -> Self {
18 Self {
19 components: Default::default(),
20 inline_subschemas: false,
21 }
22 }
23}
24
25impl ComponentsBuilder {
26 pub fn okapi_components(mut self, components: okapi::openapi3::Components) -> Self {
27 self.components = components;
28 self
29 }
30
31 pub fn inline_subschemas(mut self, inline_subschemas: bool) -> Self {
35 self.inline_subschemas = inline_subschemas;
36 self
37 }
38
39 pub fn build(self) -> Components {
40 let mut generator_settings = SchemaSettings::openapi3();
41 generator_settings.inline_subschemas = self.inline_subschemas;
42 Components {
43 generator: generator_settings.into_generator(),
44 components: self.components,
45 }
46 }
47}
48
49#[derive(Clone)]
51pub struct Components {
52 generator: SchemaGenerator,
53 components: okapi::openapi3::Components,
54}
55
56impl Components {
57 pub(crate) fn new(components: okapi::openapi3::Components) -> Self {
58 ComponentsBuilder::default()
59 .okapi_components(components)
60 .build()
61 }
62
63 pub fn schema_for<T: JsonSchema>(&mut self) -> SchemaObject {
65 let mut object = self.generator.subschema_for::<T>().into_object();
66 for visitor in self.generator.visitors_mut() {
67 visitor.visit_schema_object(&mut object);
68 }
69 object
70 }
71
72 pub fn add_security_scheme<N>(&mut self, name: N, sec: SecurityScheme)
74 where
75 N: Into<String>,
76 {
77 self.components
78 .security_schemes
79 .insert(name.into(), RefOr::Object(sec));
80 }
81
82 pub(crate) fn okapi_components(
84 &mut self,
85 ) -> Result<okapi::openapi3::Components, anyhow::Error> {
86 let mut components = self.components.clone();
87 for (name, mut schema_object) in self
88 .generator
89 .definitions()
90 .iter()
91 .map(|(n, s)| (n.clone(), s.clone().into_object()))
92 .collect::<Vec<_>>()
93 {
94 for visitor in self.generator.visitors_mut() {
95 visitor.visit_schema_object(&mut schema_object);
96 }
97 if components.schemas.contains_key(&name) {
98 return Err(anyhow::anyhow!("Multiple schemas found for '{}'", name));
99 }
100 let _ = components.schemas.insert(name, schema_object);
101 }
102 Ok(components)
103 }
104}