openapiv3_to_typescript/
generator.rs

1use std::borrow::Cow;
2
3use openapiv3::{OpenAPI, Schema};
4
5use crate::generate::path::parse_path;
6use crate::schema;
7
8#[derive(Debug)]
9pub struct Generator {
10    default_options: GeneratorOptions,
11    openapi: OpenAPI,
12}
13
14#[derive(Debug, Default, Clone)]
15pub struct GeneratorOptions {
16    /// Determines whether fields marked as `readOnly` should be included in the generated type definition.
17    ///
18    /// If `true`, fields with the `readOnly` attribute will be excluded from the type definition.
19    /// This can be useful for generating types intended for input or update operations where read-only fields should not be set.
20    ///
21    /// If `false`, fields with the `readOnly` attribute will be included in the type definition.
22    /// This is useful for generating types that represent the full structure, including fields that are read-only and should not be modified.
23    pub skip_read_only: bool,
24}
25
26#[derive(Debug)]
27pub struct PartialGeneration<'a> {
28    pub typescript: Cow<'a, str>,
29    pub references: Vec<Cow<'a, str>>,
30    pub read_only: bool,
31}
32
33impl Generator {
34    /// Creates a new instance of `Generator`.
35    ///
36    /// # Arguments
37    ///
38    /// * `openapi` - An instance of the `OpenAPI` structure representing the OpenAPI specification.
39    /// * `default_options` - An instance of `GeneratorOptions` to configure the generator's behavior.
40    ///
41    /// # Returns
42    ///
43    /// A new `Generator` instance initialized with the provided OpenAPI specification and generator options.
44    ///
45    /// # Examples
46    ///
47    /// ```
48    /// use openapiv3::OpenAPI;
49    /// use openapiv3_to_typescript::{Generator, GeneratorOptions};
50    ///
51    /// let openapi = OpenAPI::default();
52    /// let options = GeneratorOptions::default();
53    /// let generator = Generator::new(openapi, options);
54    /// ```
55    pub fn new(openapi: OpenAPI, default_options: GeneratorOptions) -> Self {
56        Self {
57            openapi,
58            default_options,
59        }
60    }
61
62    /// Generates a TypeScript type definition from an OpenAPI schema.
63    ///
64    /// # Arguments
65    ///
66    /// * `schema` - A reference to the `Schema` object from the OpenAPI specification that you want to generate the TypeScript type for.
67    /// * `options` - An optional instance of `GeneratorOptions` to override the default options for this generation.
68    ///
69    /// # Returns
70    ///
71    /// A `PartialGeneration` instance containing the generated TypeScript type definition as a string
72    /// and a vector of references that were included in the generation process.
73    ///
74    /// # Examples
75    ///
76    /// ```
77    /// use openapiv3::{OpenAPI, Schema};
78    /// use openapiv3_to_typescript::{Generator, GeneratorOptions, PartialGeneration};
79    ///
80    /// let openapi = OpenAPI::default();
81    /// let options = GeneratorOptions { skip_read_only: true };
82    /// let generator = Generator::new(openapi, options);
83    /// let schema = Schema::new_number();
84    /// let partial_generation: PartialGeneration = generator.generate_schema(&schema, None);
85    ///
86    /// println!("{:?}", partial_generation);
87    /// ```
88    pub fn generate_schema<'a>(
89        &'a self,
90        schema: &'a Schema,
91        options: Option<GeneratorOptions>,
92    ) -> PartialGeneration<'a> {
93        let cow = match options {
94            None => Cow::Borrowed(&self.default_options),
95            Some(options) => Cow::Owned(options),
96        };
97
98        schema::generate_schema(schema, cow)
99    }
100
101    pub fn generate_path(&self, operation_id: String) -> Option<PartialGeneration> {
102        self.openapi
103            .get_operation(&operation_id)
104            .map(|(op, path)| parse_path(path, op, &self.openapi))
105    }
106
107    pub fn openapi(&self) -> &OpenAPI {
108        &self.openapi
109    }
110}
111
112impl<'a> PartialGeneration<'a> {
113    pub fn typescript_mut(&mut self) -> &mut Cow<'a, str> {
114        &mut self.typescript
115    }
116}