openapi_schema_to_json_schema/
options.rs1use serde_json::Value;
4use std::fmt;
5use std::sync::Arc;
6
7use crate::consts::{NOT_SUPPORTED, STRUCTS};
8
9pub type BeforeTransform = Arc<dyn Fn(Value, &ResolvedOptions) -> Value + Send + Sync>;
14
15pub type AfterTransform = Arc<dyn Fn(Value, &ResolvedOptions) -> Value + Send + Sync>;
20
21pub type PatternPropertiesHandler = Arc<dyn Fn(Value) -> Value + Send + Sync>;
24
25#[derive(Clone, Default)]
47pub struct Options {
48 pub date_to_date_time: Option<bool>,
50 pub clone_schema: Option<bool>,
54 pub support_pattern_properties: Option<bool>,
57 pub keep_not_supported: Option<Vec<String>>,
60 pub strict_mode: Option<bool>,
62 pub remove_read_only: Option<bool>,
64 pub remove_write_only: Option<bool>,
66 pub pattern_properties_handler: Option<PatternPropertiesHandler>,
68 pub definition_keywords: Option<Vec<String>>,
71 pub before_transform: Option<BeforeTransform>,
73 pub after_transform: Option<AfterTransform>,
75}
76
77impl Options {
78 pub fn new() -> Self {
80 Self::default()
81 }
82
83 pub fn date_to_date_time(mut self, value: bool) -> Self {
85 self.date_to_date_time = Some(value);
86 self
87 }
88
89 pub fn clone_schema(mut self, value: bool) -> Self {
91 self.clone_schema = Some(value);
92 self
93 }
94
95 pub fn support_pattern_properties(mut self, value: bool) -> Self {
97 self.support_pattern_properties = Some(value);
98 self
99 }
100
101 pub fn keep_not_supported(mut self, value: Vec<String>) -> Self {
103 self.keep_not_supported = Some(value);
104 self
105 }
106
107 pub fn strict_mode(mut self, value: bool) -> Self {
109 self.strict_mode = Some(value);
110 self
111 }
112
113 pub fn remove_read_only(mut self, value: bool) -> Self {
115 self.remove_read_only = Some(value);
116 self
117 }
118
119 pub fn remove_write_only(mut self, value: bool) -> Self {
121 self.remove_write_only = Some(value);
122 self
123 }
124
125 pub fn definition_keywords(mut self, value: Vec<String>) -> Self {
127 self.definition_keywords = Some(value);
128 self
129 }
130
131 pub fn pattern_properties_handler<F>(mut self, handler: F) -> Self
134 where
135 F: Fn(Value) -> Value + Send + Sync + 'static,
136 {
137 self.pattern_properties_handler = Some(Arc::new(handler));
138 self
139 }
140
141 pub fn before_transform<F>(mut self, hook: F) -> Self
144 where
145 F: Fn(Value, &ResolvedOptions) -> Value + Send + Sync + 'static,
146 {
147 self.before_transform = Some(Arc::new(hook));
148 self
149 }
150
151 pub fn after_transform<F>(mut self, hook: F) -> Self
154 where
155 F: Fn(Value, &ResolvedOptions) -> Value + Send + Sync + 'static,
156 {
157 self.after_transform = Some(Arc::new(hook));
158 self
159 }
160}
161
162impl fmt::Debug for Options {
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 f.debug_struct("Options")
165 .field("date_to_date_time", &self.date_to_date_time)
166 .field("clone_schema", &self.clone_schema)
167 .field(
168 "support_pattern_properties",
169 &self.support_pattern_properties,
170 )
171 .field("keep_not_supported", &self.keep_not_supported)
172 .field("strict_mode", &self.strict_mode)
173 .field("remove_read_only", &self.remove_read_only)
174 .field("remove_write_only", &self.remove_write_only)
175 .field(
176 "pattern_properties_handler",
177 &closure_field(self.pattern_properties_handler.is_some()),
178 )
179 .field("definition_keywords", &self.definition_keywords)
180 .field(
181 "before_transform",
182 &closure_field(self.before_transform.is_some()),
183 )
184 .field(
185 "after_transform",
186 &closure_field(self.after_transform.is_some()),
187 )
188 .finish()
189 }
190}
191
192fn closure_field(set: bool) -> &'static str {
194 if set {
195 "Some(<closure>)"
196 } else {
197 "None"
198 }
199}
200
201#[derive(Clone)]
215pub struct ResolvedOptions {
216 pub(crate) date_to_date_time: bool,
217 pub(crate) support_pattern_properties: bool,
218 pub(crate) strict_mode: bool,
219 pub(crate) definition_keywords: Vec<String>,
220 pub(crate) pattern_properties_handler: Option<PatternPropertiesHandler>,
221 pub(crate) before_transform: Option<BeforeTransform>,
222 pub(crate) after_transform: Option<AfterTransform>,
223 pub(crate) remove_props: Vec<&'static str>,
226 pub(crate) not_supported: Vec<&'static str>,
229}
230
231pub(crate) fn resolve_options(options: &Options) -> ResolvedOptions {
237 let date_to_date_time = options.date_to_date_time.unwrap_or(false);
238 let support_pattern_properties = options.support_pattern_properties.unwrap_or(false);
239 let keep_not_supported = options.keep_not_supported.clone().unwrap_or_default();
240 let definition_keywords = options.definition_keywords.clone().unwrap_or_default();
241 let strict_mode = options.strict_mode.unwrap_or(true);
242
243 let mut remove_props = Vec::new();
244 if options.remove_read_only.unwrap_or(false) {
245 remove_props.push("readOnly");
246 }
247 if options.remove_write_only.unwrap_or(false) {
248 remove_props.push("writeOnly");
249 }
250
251 let not_supported: Vec<&'static str> = NOT_SUPPORTED
252 .iter()
253 .copied()
254 .filter(|kw| !keep_not_supported.iter().any(|k| k == kw))
255 .collect();
256
257 ResolvedOptions {
258 date_to_date_time,
259 support_pattern_properties,
260 strict_mode,
261 definition_keywords,
262 pattern_properties_handler: options.pattern_properties_handler.clone(),
263 before_transform: options.before_transform.clone(),
264 after_transform: options.after_transform.clone(),
265 remove_props,
266 not_supported,
267 }
268}
269
270impl ResolvedOptions {
271 pub(crate) const STRUCTS: &'static [&'static str] = STRUCTS;
273
274 pub fn date_to_date_time(&self) -> bool {
276 self.date_to_date_time
277 }
278
279 pub fn support_pattern_properties(&self) -> bool {
281 self.support_pattern_properties
282 }
283
284 pub fn strict_mode(&self) -> bool {
286 self.strict_mode
287 }
288
289 pub fn definition_keywords(&self) -> &[String] {
291 &self.definition_keywords
292 }
293}
294
295impl fmt::Debug for ResolvedOptions {
296 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
297 f.debug_struct("ResolvedOptions")
298 .field("date_to_date_time", &self.date_to_date_time)
299 .field(
300 "support_pattern_properties",
301 &self.support_pattern_properties,
302 )
303 .field("strict_mode", &self.strict_mode)
304 .field("definition_keywords", &self.definition_keywords)
305 .field(
306 "pattern_properties_handler",
307 &closure_field(self.pattern_properties_handler.is_some()),
308 )
309 .field(
310 "before_transform",
311 &closure_field(self.before_transform.is_some()),
312 )
313 .field(
314 "after_transform",
315 &closure_field(self.after_transform.is_some()),
316 )
317 .field("remove_props", &self.remove_props)
318 .field("not_supported", &self.not_supported)
319 .finish()
320 }
321}