Skip to main content

salvo_oapi/swagger_ui/
config.rs

1use std::borrow::Cow;
2
3use serde::Serialize;
4
5use super::oauth;
6use crate::swagger_ui::Url;
7
8const SWAGGER_STANDALONE_LAYOUT: &str = "StandaloneLayout";
9const SWAGGER_BASE_LAYOUT: &str = "BaseLayout";
10
11/// Object used to alter Swagger UI settings.
12///
13/// Config struct provides [Swagger UI configuration](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md)
14/// for settings which could be altered with **docker variables**.
15///
16/// # Examples
17///
18/// In simple case create config directly from url that points to the api doc json.
19/// ```rust
20/// # use salvo_oapi::swagger_ui::Config;
21/// let config = Config::from("/api-doc.json");
22/// ```
23///
24/// If there is multiple api docs to serve config can be also directly created with [`Config::new`]
25/// ```rust
26/// # use salvo_oapi::swagger_ui::Config;
27/// let config = Config::new(["/api-docs/openapi1.json", "/api-docs/openapi2.json"]);
28/// ```
29///
30/// Or same as above but more verbose syntax.
31/// ```rust
32/// # use salvo_oapi::swagger_ui::{Config, Url};
33/// let config = Config::new([
34///     Url::new("api1", "/api-docs/openapi1.json"),
35///     Url::new("api2", "/api-docs/openapi2.json")
36/// ]);
37/// ```
38///
39/// With oauth config.
40/// ```rust
41/// # use salvo_oapi::swagger_ui::{Config, oauth};
42/// let config = Config::with_oauth_config(
43///     ["/api-docs/openapi1.json", "/api-docs/openapi2.json"],
44///     oauth::Config::new(),
45/// );
46/// ```
47#[non_exhaustive]
48#[derive(Serialize, Clone, Debug)]
49#[serde(rename_all = "camelCase")]
50pub struct Config<'a> {
51    /// Url to fetch external configuration from.
52    #[serde(skip_serializing_if = "Option::is_none")]
53    pub(crate) config_url: Option<String>,
54
55    /// Id of the DOM element where `Swagger UI` will put it's user interface.
56    #[serde(skip_serializing_if = "Option::is_none")]
57    #[serde(rename = "dom_id")]
58    pub(crate) dom_id: Option<String>,
59
60    /// [`Url`] the Swagger UI is serving.
61    #[serde(skip_serializing_if = "Option::is_none")]
62    pub(crate) url: Option<String>,
63
64    /// Name of the primary url if any.
65    #[serde(skip_serializing_if = "Option::is_none", rename = "urls.primaryName")]
66    pub(crate) urls_primary_name: Option<String>,
67
68    /// [`Url`]s the Swagger UI is serving.
69    #[serde(skip_serializing_if = "Vec::is_empty")]
70    pub(crate) urls: Vec<Url<'a>>,
71
72    /// Enables overriding configuration parameters with url query parameters.
73    #[serde(skip_serializing_if = "Option::is_none")]
74    pub(crate) query_config_enabled: Option<bool>,
75
76    /// Controls whether [deep linking](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/deep-linking.md)
77    /// is enabled in OpenAPI spec.
78    ///
79    /// Deep linking automatically scrolls and expands UI to given url fragment.
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub(crate) deep_linking: Option<bool>,
82
83    /// Controls whether operation id is shown in the operation list.
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub(crate) display_operation_id: Option<bool>,
86
87    /// Default models expansion depth; -1 will completely hide the models.
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub(crate) default_models_expand_depth: Option<isize>,
90
91    /// Default model expansion depth from model example section.
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub(crate) default_model_expand_depth: Option<isize>,
94
95    /// Defines how models is show when API is first rendered.
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub(crate) default_model_rendering: Option<String>,
98
99    /// Define whether request duration in milliseconds is displayed for "Try it out" requests.
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub(crate) display_request_duration: Option<bool>,
102
103    /// Controls default expansion for operations and tags.
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub(crate) doc_expansion: Option<String>,
106
107    /// Defines is filtering of tagged operations allowed with edit box in top bar.
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub(crate) filter: Option<bool>,
110
111    /// Controls how many tagged operations are shown. By default all operations are shown.
112    #[serde(skip_serializing_if = "Option::is_none")]
113    pub(crate) max_displayed_tags: Option<usize>,
114
115    /// Defines whether extensions are shown.
116    #[serde(skip_serializing_if = "Option::is_none")]
117    pub(crate) show_extensions: Option<bool>,
118
119    /// Defines whether common extensions are shown.
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub(crate) show_common_extensions: Option<bool>,
122
123    /// Defines whether "Try it out" section should be enabled by default.
124    #[serde(skip_serializing_if = "Option::is_none")]
125    pub(crate) try_it_out_enabled: Option<bool>,
126
127    /// Defines whether request snippets section is enabled. If disabled legacy curl snipped
128    /// will be used.
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub(crate) request_snippets_enabled: Option<bool>,
131
132    /// Oauth redirect url.
133    #[serde(skip_serializing_if = "Option::is_none")]
134    pub(crate) oauth2_redirect_url: Option<String>,
135
136    /// Defines whether request mutated with `requestInterceptor` will be used to produce curl command
137    /// in the UI.
138    #[serde(skip_serializing_if = "Option::is_none")]
139    pub(crate) show_mutated_request: Option<bool>,
140
141    /// Define supported http request submit methods.
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub(crate) supported_submit_methods: Option<Vec<String>>,
144
145    /// Define validator url which is used to validate the Swagger spec. By default the validator swagger.io's
146    /// online validator is used. Setting this to none will disable spec validation.
147    #[serde(skip_serializing_if = "Option::is_none")]
148    pub(crate) validator_url: Option<String>,
149
150    /// Enables passing credentials to CORS requests as defined
151    /// [fetch standards](https://fetch.spec.whatwg.org/#credentials).
152    #[serde(skip_serializing_if = "Option::is_none")]
153    pub(crate) with_credentials: Option<bool>,
154
155    /// Defines whether authorizations is persisted throughout browser refresh and close.
156    #[serde(skip_serializing_if = "Option::is_none")]
157    pub(crate) persist_authorization: Option<bool>,
158
159    /// [`oauth::Config`] the Swagger UI is using for auth flow.
160    #[serde(skip)]
161    pub(crate) oauth: Option<oauth::Config>,
162
163    /// The layout of Swagger UI uses, default is `"StandaloneLayout"`
164    pub(crate) layout: &'a str,
165}
166
167impl<'a> Config<'a> {
168    fn new_<I: IntoIterator<Item = U>, U: Into<Url<'a>>>(urls: I, oauth_config: Option<oauth::Config>) -> Self {
169        let urls = urls.into_iter().map(Into::into).collect::<Vec<Url<'a>>>();
170        let urls_len = urls.len();
171
172        Self {
173            oauth: oauth_config,
174            ..if urls_len == 1 {
175                Self::new_config_with_single_url(urls)
176            } else {
177                Self::new_config_with_multiple_urls(urls)
178            }
179        }
180    }
181
182    fn new_config_with_multiple_urls(urls: Vec<Url<'a>>) -> Self {
183        let primary_name = urls.iter().find(|url| url.primary).map(|url| url.name.to_string());
184
185        Self {
186            urls_primary_name: primary_name,
187            urls: urls
188                .into_iter()
189                .map(|mut url| {
190                    if url.name.is_empty() {
191                        url.name = Cow::Owned(String::from(&url.url[..]));
192
193                        url
194                    } else {
195                        url
196                    }
197                })
198                .collect(),
199            ..Default::default()
200        }
201    }
202
203    fn new_config_with_single_url(mut urls: Vec<Url<'a>>) -> Self {
204        let url = urls.get_mut(0).map(std::mem::take).expect("urls should not be empty");
205        let primary_name = if url.primary { Some(url.name.to_string()) } else { None };
206
207        Self {
208            urls_primary_name: primary_name,
209            url: if url.name.is_empty() {
210                Some(url.url.to_string())
211            } else {
212                None
213            },
214            urls: if !url.name.is_empty() { vec![url] } else { Vec::new() },
215            ..Default::default()
216        }
217    }
218
219    /// Constructs a new [`Config`] from [`Iterator`] of [`Url`]s.
220    ///
221    /// [`Url`]s provided to the [`Config`] will only change the urls Swagger UI is going to use to
222    /// fetch the API document.
223    ///
224    /// # Examples
225    /// Create new config with 2 api doc urls.
226    /// ```rust
227    /// # use salvo_oapi::swagger_ui::Config;
228    /// let config = Config::new(["/api-docs/openapi1.json", "/api-docs/openapi2.json"]);
229    /// ```
230    pub fn new<I: IntoIterator<Item = U>, U: Into<Url<'a>>>(urls: I) -> Self {
231        Self::new_(urls, None)
232    }
233
234    /// Constructs a new [`Config`] from [`Iterator`] of [`Url`]s.
235    ///
236    /// # Examples
237    /// Create new config with oauth config.
238    /// ```rust
239    /// # use salvo_oapi::swagger_ui::{Config, oauth};
240    /// let config = Config::with_oauth_config(
241    ///     ["/api-docs/openapi1.json", "/api-docs/openapi2.json"],
242    ///     oauth::Config::new(),
243    /// );
244    /// ```
245    pub fn with_oauth_config<I: IntoIterator<Item = U>, U: Into<Url<'a>>>(
246        urls: I,
247        oauth_config: oauth::Config,
248    ) -> Self {
249        Self::new_(urls, Some(oauth_config))
250    }
251
252    /// Add url to fetch external configuration from.
253    ///
254    /// # Examples
255    ///
256    /// Set external config url.
257    /// ```rust
258    /// # use salvo_oapi::swagger_ui::Config;
259    /// let config = Config::new(["/api-docs/openapi.json"])
260    ///     .config_url("http://url.to.external.config");
261    /// ```
262    #[must_use]
263    pub fn config_url<S: Into<String>>(mut self, config_url: S) -> Self {
264        self.config_url = Some(config_url.into());
265
266        self
267    }
268
269    /// Add id of the DOM element where `Swagger UI` will put it's user interface.
270    ///
271    /// The default value is `#swagger-ui`.
272    ///
273    /// # Examples
274    ///
275    /// Set custom dom id where the Swagger UI will place it's content.
276    /// ```rust
277    /// # use salvo_oapi::swagger_ui::Config;
278    /// let config = Config::new(["/api-docs/openapi.json"]).dom_id("#my-id");
279    /// ```
280    #[must_use]
281    pub fn dom_id<S: Into<String>>(mut self, dom_id: S) -> Self {
282        self.dom_id = Some(dom_id.into());
283
284        self
285    }
286
287    /// Set `query_config_enabled` to allow overriding configuration parameters via url `query`
288    /// parameters.
289    ///
290    /// Default value is `false`.
291    ///
292    /// # Examples
293    ///
294    /// Enable query config.
295    /// ```rust
296    /// # use salvo_oapi::swagger_ui::Config;
297    /// let config = Config::new(["/api-docs/openapi.json"])
298    ///     .query_config_enabled(true);
299    /// ```
300    #[must_use] pub fn query_config_enabled(mut self, query_config_enabled: bool) -> Self {
301        self.query_config_enabled = Some(query_config_enabled);
302
303        self
304    }
305
306    /// Set `deep_linking` to allow deep linking tags and operations.
307    ///
308    /// Deep linking will automatically scroll to and expand operation when Swagger UI is
309    /// given corresponding url fragment. See more at
310    /// [deep linking docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/deep-linking.md).
311    ///
312    /// Deep linking is enabled by default.
313    ///
314    /// # Examples
315    ///
316    /// Disable the deep linking.
317    /// ```rust
318    /// # use salvo_oapi::swagger_ui::Config;
319    /// let config = Config::new(["/api-docs/openapi.json"])
320    ///     .deep_linking(false);
321    /// ```
322    #[must_use] pub fn deep_linking(mut self, deep_linking: bool) -> Self {
323        self.deep_linking = Some(deep_linking);
324
325        self
326    }
327
328    /// Set `display_operation_id` to `true` to show operation id in the operations list.
329    ///
330    /// Default value is `false`.
331    ///
332    /// # Examples
333    ///
334    /// Allow operation id to be shown.
335    /// ```rust
336    /// # use salvo_oapi::swagger_ui::Config;
337    /// let config = Config::new(["/api-docs/openapi.json"])
338    ///     .display_operation_id(true);
339    /// ```
340    #[must_use] pub fn display_operation_id(mut self, display_operation_id: bool) -> Self {
341        self.display_operation_id = Some(display_operation_id);
342
343        self
344    }
345
346    /// Set 'layout' to 'BaseLayout' to only use the base swagger layout without a search header.
347    ///
348    /// Default value is 'StandaloneLayout'.
349    ///
350    /// # Examples
351    ///
352    /// Configure Swagger to use Base Layout instead of Standalone
353    /// ```rust
354    /// # use salvo_oapi::swagger_ui::Config;
355    /// let config = Config::new(["/api-docs/openapi.json"])
356    ///     .use_base_layout();
357    /// ```
358    #[must_use] pub fn use_base_layout(mut self) -> Self {
359        self.layout = SWAGGER_BASE_LAYOUT;
360
361        self
362    }
363
364    /// Add default models expansion depth.
365    ///
366    /// Setting this to `-1` will completely hide the models.
367    ///
368    /// # Examples
369    ///
370    /// Hide all the models.
371    /// ```rust
372    /// # use salvo_oapi::swagger_ui::Config;
373    /// let config = Config::new(["/api-docs/openapi.json"])
374    ///     .default_models_expand_depth(-1);
375    /// ```
376    #[must_use] pub fn default_models_expand_depth(mut self, default_models_expand_depth: isize) -> Self {
377        self.default_models_expand_depth = Some(default_models_expand_depth);
378
379        self
380    }
381
382    /// Add default model expansion depth for model on the example section.
383    ///
384    /// # Examples
385    ///
386    /// ```rust
387    /// # use salvo_oapi::swagger_ui::Config;
388    /// let config = Config::new(["/api-docs/openapi.json"])
389    ///     .default_model_expand_depth(1);
390    /// ```
391    #[must_use] pub fn default_model_expand_depth(mut self, default_model_expand_depth: isize) -> Self {
392        self.default_model_expand_depth = Some(default_model_expand_depth);
393
394        self
395    }
396
397    /// Add `default_model_rendering` to set how models is show when API is first rendered.
398    ///
399    /// The user can always switch the rendering for given model by clicking the `Model` and `Example Value` links.
400    ///
401    /// * `example` Makes example rendered first by default.
402    /// * `model` Makes model rendered first by default.
403    ///
404    /// # Examples
405    ///
406    /// ```rust
407    /// # use salvo_oapi::swagger_ui::Config;
408    /// let config = Config::new(["/api-docs/openapi.json"])
409    ///     .default_model_rendering(r#"["example"*, "model"]"#);
410    /// ```
411    #[must_use]
412    pub fn default_model_rendering<S: Into<String>>(mut self, default_model_rendering: S) -> Self {
413        self.default_model_rendering = Some(default_model_rendering.into());
414
415        self
416    }
417
418    /// Set to `true` to show request duration of _**'Try it out'**_ requests _**(in milliseconds)**_.
419    ///
420    /// Default value is `false`.
421    ///
422    /// # Examples
423    /// Enable request duration of the _**'Try it out'**_ requests.
424    /// ```rust
425    /// # use salvo_oapi::swagger_ui::Config;
426    /// let config = Config::new(["/api-docs/openapi.json"])
427    ///     .display_request_duration(true);
428    /// ```
429    #[must_use] pub fn display_request_duration(mut self, display_request_duration: bool) -> Self {
430        self.display_request_duration = Some(display_request_duration);
431
432        self
433    }
434
435    /// Add `doc_expansion` to control default expansion for operations and tags.
436    ///
437    /// * `list` Will expand only tags.
438    /// * `full` Will expand tags and operations.
439    /// * `none` Will expand nothing.
440    ///
441    /// # Examples
442    ///
443    /// ```rust
444    /// # use salvo_oapi::swagger_ui::Config;
445    /// let config = Config::new(["/api-docs/openapi.json"])
446    ///     .doc_expansion(r#"["list"*, "full", "none"]"#);
447    /// ```
448    #[must_use]
449    pub fn doc_expansion<S: Into<String>>(mut self, doc_expansion: S) -> Self {
450        self.doc_expansion = Some(doc_expansion.into());
451
452        self
453    }
454
455    /// Add `filter` to allow filtering of tagged operations.
456    ///
457    /// When enabled top bar will show and edit box that can be used to filter visible tagged operations.
458    /// Filter behaves case sensitive manner and matches anywhere inside the tag.
459    ///
460    /// Default value is `false`.
461    ///
462    /// # Examples
463    ///
464    /// Enable filtering.
465    /// ```rust
466    /// # use salvo_oapi::swagger_ui::Config;
467    /// let config = Config::new(["/api-docs/openapi.json"])
468    ///     .filter(true);
469    /// ```
470    #[must_use] pub fn filter(mut self, filter: bool) -> Self {
471        self.filter = Some(filter);
472
473        self
474    }
475
476    /// Add `max_displayed_tags` to restrict shown tagged operations.
477    ///
478    /// By default all operations are shown.
479    ///
480    /// # Examples
481    ///
482    /// Display only 4 operations.
483    /// ```rust
484    /// # use salvo_oapi::swagger_ui::Config;
485    /// let config = Config::new(["/api-docs/openapi.json"])
486    ///     .max_displayed_tags(4);
487    /// ```
488    #[must_use] pub fn max_displayed_tags(mut self, max_displayed_tags: usize) -> Self {
489        self.max_displayed_tags = Some(max_displayed_tags);
490
491        self
492    }
493
494    /// Set `show_extensions` to adjust whether vendor extension _**`(x-)`**_ fields and values
495    /// are shown for operations, parameters, responses and schemas.
496    ///
497    /// # Example
498    ///
499    /// Show vendor extensions.
500    /// ```rust
501    /// # use salvo_oapi::swagger_ui::Config;
502    /// let config = Config::new(["/api-docs/openapi.json"])
503    ///     .show_extensions(true);
504    /// ```
505    #[must_use] pub fn show_extensions(mut self, show_extensions: bool) -> Self {
506        self.show_extensions = Some(show_extensions);
507
508        self
509    }
510
511    /// Add `show_common_extensions` to define whether common extension
512    /// _**`(pattern, maxLength, minLength, maximum, minimum)`**_ fields and values are shown
513    /// for parameters.
514    ///
515    /// # Examples
516    ///
517    /// Show common extensions.
518    /// ```rust
519    /// # use salvo_oapi::swagger_ui::Config;
520    /// let config = Config::new(["/api-docs/openapi.json"])
521    ///     .show_common_extensions(true);
522    /// ```
523    #[must_use] pub fn show_common_extensions(mut self, show_common_extensions: bool) -> Self {
524        self.show_common_extensions = Some(show_common_extensions);
525
526        self
527    }
528
529    /// Add `try_it_out_enabled` to enable _**'Try it out'**_ section by default.
530    ///
531    /// Default value is `false`.
532    ///
533    /// # Examples
534    ///
535    /// Enable _**'Try it out'**_ section by default.
536    /// ```rust
537    /// # use salvo_oapi::swagger_ui::Config;
538    /// let config = Config::new(["/api-docs/openapi.json"])
539    ///     .try_it_out_enabled(true);
540    /// ```
541    #[must_use] pub fn try_it_out_enabled(mut self, try_it_out_enabled: bool) -> Self {
542        self.try_it_out_enabled = Some(try_it_out_enabled);
543
544        self
545    }
546
547    /// Set `request_snippets_enabled` to enable request snippets section.
548    ///
549    /// If disabled legacy curl snipped will be used.
550    ///
551    /// Default value is `false`.
552    ///
553    /// # Examples
554    ///
555    /// Enable request snippets section.
556    /// ```rust
557    /// # use salvo_oapi::swagger_ui::Config;
558    /// let config = Config::new(["/api-docs/openapi.json"])
559    ///     .request_snippets_enabled(true);
560    /// ```
561    #[must_use] pub fn request_snippets_enabled(mut self, request_snippets_enabled: bool) -> Self {
562        self.request_snippets_enabled = Some(request_snippets_enabled);
563
564        self
565    }
566
567    /// Add oauth redirect url.
568    ///
569    /// # Examples
570    ///
571    /// Add oauth redirect url.
572    /// ```rust
573    /// # use salvo_oapi::swagger_ui::Config;
574    /// let config = Config::new(["/api-docs/openapi.json"])
575    ///     .oauth2_redirect_url("http://my.oauth2.redirect.url");
576    /// ```
577    #[must_use]
578    pub fn oauth2_redirect_url<S: Into<String>>(mut self, oauth2_redirect_url: S) -> Self {
579        self.oauth2_redirect_url = Some(oauth2_redirect_url.into());
580
581        self
582    }
583
584    /// Add `show_mutated_request` to use request returned from `requestInterceptor`
585    /// to produce curl command in the UI. If set to `false` the request before `requestInterceptor`
586    /// was applied will be used.
587    ///
588    /// # Examples
589    ///
590    /// Use request after `requestInterceptor` to produce the curl command.
591    /// ```rust
592    /// # use salvo_oapi::swagger_ui::Config;
593    /// let config = Config::new(["/api-docs/openapi.json"])
594    ///     .show_mutated_request(true);
595    /// ```
596    #[must_use] pub fn show_mutated_request(mut self, show_mutated_request: bool) -> Self {
597        self.show_mutated_request = Some(show_mutated_request);
598
599        self
600    }
601
602    /// Add supported http methods for _**'Try it out'**_ operation.
603    ///
604    /// _**'Try it out'**_ will be enabled based on the given list of http methods when
605    /// the operation's http method is included within the list.
606    /// By giving an empty list will disable _**'Try it out'**_ from all operations but it will
607    /// **not** filter operations from the UI.
608    ///
609    /// By default all http operations are enabled.
610    ///
611    /// # Examples
612    ///
613    /// Set allowed http methods explicitly.
614    /// ```rust
615    /// # use salvo_oapi::swagger_ui::Config;
616    /// let config = Config::new(["/api-docs/openapi.json"])
617    ///     .supported_submit_methods(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
618    /// ```
619    ///
620    /// Allow _**'Try it out'**_ for only GET operations.
621    /// ```rust
622    /// # use salvo_oapi::swagger_ui::Config;
623    /// let config = Config::new(["/api-docs/openapi.json"])
624    ///     .supported_submit_methods(["get"]);
625    /// ```
626    #[must_use]
627    pub fn supported_submit_methods<I: IntoIterator<Item = S>, S: Into<String>>(
628        mut self,
629        supported_submit_methods: I,
630    ) -> Self {
631        self.supported_submit_methods = Some(
632            supported_submit_methods
633                .into_iter()
634                .map(|method| method.into())
635                .collect(),
636        );
637
638        self
639    }
640
641    /// Add validator url which is used to validate the Swagger spec.
642    ///
643    /// This can also be set to use locally deployed validator for example see
644    /// [Validator Badge](https://github.com/swagger-api/validator-badge) for more details.
645    ///
646    /// By default swagger.io's online validator _**`(https://validator.swagger.io/validator)`**_ will be used.
647    /// Setting this to `none` will disable the validator.
648    ///
649    /// # Examples
650    ///
651    /// Disable the validator.
652    /// ```rust
653    /// # use salvo_oapi::swagger_ui::Config;
654    /// let config = Config::new(["/api-docs/openapi.json"])
655    ///     .validator_url("none");
656    /// ```
657    #[must_use]
658    pub fn validator_url<S: Into<String>>(mut self, validator_url: S) -> Self {
659        self.validator_url = Some(validator_url.into());
660
661        self
662    }
663
664    /// Set `with_credentials` to enable passing credentials to CORS requests send by browser as defined
665    /// [fetch standards](https://fetch.spec.whatwg.org/#credentials).
666    ///
667    /// **Note**: that Swagger UI cannot currently set cookies cross-domain
668    /// (see [swagger-js#1163](https://github.com/swagger-api/swagger-js/issues/1163)) -
669    /// as a result, you will have to rely on browser-supplied cookies (which this setting enables sending)
670    /// that Swagger UI cannot control.
671    ///
672    /// # Examples
673    ///
674    /// Enable passing credentials to CORS requests.
675    /// ```rust
676    /// # use salvo_oapi::swagger_ui::Config;
677    /// let config = Config::new(["/api-docs/openapi.json"])
678    ///     .with_credentials(true);
679    /// ```
680    #[must_use] pub fn with_credentials(mut self, with_credentials: bool) -> Self {
681        self.with_credentials = Some(with_credentials);
682
683        self
684    }
685
686    /// Set to `true` to enable authorizations to be persisted throughout browser refresh and close.
687    ///
688    /// Default value is `false`.
689    ///
690    ///
691    /// # Examples
692    ///
693    /// Persists authorization throughout browser close and refresh.
694    /// ```rust
695    /// # use salvo_oapi::swagger_ui::Config;
696    /// let config = Config::new(["/api-docs/openapi.json"])
697    ///     .persist_authorization(true);
698    /// ```
699    #[must_use] pub fn persist_authorization(mut self, persist_authorization: bool) -> Self {
700        self.persist_authorization = Some(persist_authorization);
701
702        self
703    }
704}
705
706impl Default for Config<'_> {
707    fn default() -> Self {
708        Self {
709            config_url: Default::default(),
710            dom_id: Some("#swagger-ui".to_owned()),
711            url: Default::default(),
712            urls_primary_name: Default::default(),
713            urls: Default::default(),
714            query_config_enabled: Default::default(),
715            deep_linking: Some(true),
716            display_operation_id: Default::default(),
717            default_models_expand_depth: Default::default(),
718            default_model_expand_depth: Default::default(),
719            default_model_rendering: Default::default(),
720            display_request_duration: Default::default(),
721            doc_expansion: Default::default(),
722            filter: Default::default(),
723            max_displayed_tags: Default::default(),
724            show_extensions: Default::default(),
725            show_common_extensions: Default::default(),
726            try_it_out_enabled: Default::default(),
727            request_snippets_enabled: Default::default(),
728            oauth2_redirect_url: Default::default(),
729            show_mutated_request: Default::default(),
730            supported_submit_methods: Default::default(),
731            validator_url: Default::default(),
732            with_credentials: Default::default(),
733            persist_authorization: Default::default(),
734            oauth: Default::default(),
735            layout: SWAGGER_STANDALONE_LAYOUT,
736        }
737    }
738}
739
740impl<'a> From<&'a str> for Config<'a> {
741    fn from(s: &'a str) -> Self {
742        Self::new([s])
743    }
744}
745
746impl From<String> for Config<'_> {
747    fn from(s: String) -> Self {
748        Self::new([s])
749    }
750}