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
184            .iter()
185            .find(|url| url.primary)
186            .map(|url| url.name.as_ref().to_owned());
187
188        Self {
189            urls_primary_name: primary_name,
190            urls: urls
191                .into_iter()
192                .map(|mut url| {
193                    if url.name.is_empty() {
194                        url.name = Cow::Owned(String::from(&url.url[..]));
195
196                        url
197                    } else {
198                        url
199                    }
200                })
201                .collect(),
202            ..Default::default()
203        }
204    }
205
206    fn new_config_with_single_url(mut urls: Vec<Url<'a>>) -> Self {
207        let url = urls.get_mut(0).map(std::mem::take).expect("urls should not be empty");
208        let primary_name = if url.primary {
209            Some(url.name.as_ref().to_owned())
210        } else {
211            None
212        };
213
214        Self {
215            urls_primary_name: primary_name,
216            url: if url.name.is_empty() {
217                Some(url.url.as_ref().to_owned())
218            } else {
219                None
220            },
221            urls: if !url.name.is_empty() { vec![url] } else { Vec::new() },
222            ..Default::default()
223        }
224    }
225
226    /// Constructs a new [`Config`] from [`Iterator`] of [`Url`]s.
227    ///
228    /// [`Url`]s provided to the [`Config`] will only change the urls Swagger UI is going to use to
229    /// fetch the API document.
230    ///
231    /// # Examples
232    /// Create new config with 2 api doc urls.
233    /// ```rust
234    /// # use salvo_oapi::swagger_ui::Config;
235    /// let config = Config::new(["/api-docs/openapi1.json", "/api-docs/openapi2.json"]);
236    /// ```
237    pub fn new<I: IntoIterator<Item = U>, U: Into<Url<'a>>>(urls: I) -> Self {
238        Self::new_(urls, None)
239    }
240
241    /// Constructs a new [`Config`] from [`Iterator`] of [`Url`]s.
242    ///
243    /// # Examples
244    /// Create new config with oauth config.
245    /// ```rust
246    /// # use salvo_oapi::swagger_ui::{Config, oauth};
247    /// let config = Config::with_oauth_config(
248    ///     ["/api-docs/openapi1.json", "/api-docs/openapi2.json"],
249    ///     oauth::Config::new(),
250    /// );
251    /// ```
252    pub fn with_oauth_config<I: IntoIterator<Item = U>, U: Into<Url<'a>>>(
253        urls: I,
254        oauth_config: oauth::Config,
255    ) -> Self {
256        Self::new_(urls, Some(oauth_config))
257    }
258
259    /// Add url to fetch external configuration from.
260    ///
261    /// # Examples
262    ///
263    /// Set external config url.
264    /// ```rust
265    /// # use salvo_oapi::swagger_ui::Config;
266    /// let config = Config::new(["/api-docs/openapi.json"])
267    ///     .config_url("http://url.to.external.config");
268    /// ```
269    #[must_use]
270    pub fn config_url<S: Into<String>>(mut self, config_url: S) -> Self {
271        self.config_url = Some(config_url.into());
272
273        self
274    }
275
276    /// Add id of the DOM element where `Swagger UI` will put it's user interface.
277    ///
278    /// The default value is `#swagger-ui`.
279    ///
280    /// # Examples
281    ///
282    /// Set custom dom id where the Swagger UI will place it's content.
283    /// ```rust
284    /// # use salvo_oapi::swagger_ui::Config;
285    /// let config = Config::new(["/api-docs/openapi.json"]).dom_id("#my-id");
286    /// ```
287    #[must_use]
288    pub fn dom_id<S: Into<String>>(mut self, dom_id: S) -> Self {
289        self.dom_id = Some(dom_id.into());
290
291        self
292    }
293
294    /// Set `query_config_enabled` to allow overriding configuration parameters via url `query`
295    /// parameters.
296    ///
297    /// Default value is `false`.
298    ///
299    /// # Examples
300    ///
301    /// Enable query config.
302    /// ```rust
303    /// # use salvo_oapi::swagger_ui::Config;
304    /// let config = Config::new(["/api-docs/openapi.json"])
305    ///     .query_config_enabled(true);
306    /// ```
307    #[must_use] pub fn query_config_enabled(mut self, query_config_enabled: bool) -> Self {
308        self.query_config_enabled = Some(query_config_enabled);
309
310        self
311    }
312
313    /// Set `deep_linking` to allow deep linking tags and operations.
314    ///
315    /// Deep linking will automatically scroll to and expand operation when Swagger UI is
316    /// given corresponding url fragment. See more at
317    /// [deep linking docs](https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/deep-linking.md).
318    ///
319    /// Deep linking is enabled by default.
320    ///
321    /// # Examples
322    ///
323    /// Disable the deep linking.
324    /// ```rust
325    /// # use salvo_oapi::swagger_ui::Config;
326    /// let config = Config::new(["/api-docs/openapi.json"])
327    ///     .deep_linking(false);
328    /// ```
329    #[must_use] pub fn deep_linking(mut self, deep_linking: bool) -> Self {
330        self.deep_linking = Some(deep_linking);
331
332        self
333    }
334
335    /// Set `display_operation_id` to `true` to show operation id in the operations list.
336    ///
337    /// Default value is `false`.
338    ///
339    /// # Examples
340    ///
341    /// Allow operation id to be shown.
342    /// ```rust
343    /// # use salvo_oapi::swagger_ui::Config;
344    /// let config = Config::new(["/api-docs/openapi.json"])
345    ///     .display_operation_id(true);
346    /// ```
347    #[must_use] pub fn display_operation_id(mut self, display_operation_id: bool) -> Self {
348        self.display_operation_id = Some(display_operation_id);
349
350        self
351    }
352
353    /// Set 'layout' to 'BaseLayout' to only use the base swagger layout without a search header.
354    ///
355    /// Default value is 'StandaloneLayout'.
356    ///
357    /// # Examples
358    ///
359    /// Configure Swagger to use Base Layout instead of Standalone
360    /// ```rust
361    /// # use salvo_oapi::swagger_ui::Config;
362    /// let config = Config::new(["/api-docs/openapi.json"])
363    ///     .use_base_layout();
364    /// ```
365    #[must_use] pub fn use_base_layout(mut self) -> Self {
366        self.layout = SWAGGER_BASE_LAYOUT;
367
368        self
369    }
370
371    /// Add default models expansion depth.
372    ///
373    /// Setting this to `-1` will completely hide the models.
374    ///
375    /// # Examples
376    ///
377    /// Hide all the models.
378    /// ```rust
379    /// # use salvo_oapi::swagger_ui::Config;
380    /// let config = Config::new(["/api-docs/openapi.json"])
381    ///     .default_models_expand_depth(-1);
382    /// ```
383    #[must_use] pub fn default_models_expand_depth(mut self, default_models_expand_depth: isize) -> Self {
384        self.default_models_expand_depth = Some(default_models_expand_depth);
385
386        self
387    }
388
389    /// Add default model expansion depth for model on the example section.
390    ///
391    /// # Examples
392    ///
393    /// ```rust
394    /// # use salvo_oapi::swagger_ui::Config;
395    /// let config = Config::new(["/api-docs/openapi.json"])
396    ///     .default_model_expand_depth(1);
397    /// ```
398    #[must_use] pub fn default_model_expand_depth(mut self, default_model_expand_depth: isize) -> Self {
399        self.default_model_expand_depth = Some(default_model_expand_depth);
400
401        self
402    }
403
404    /// Add `default_model_rendering` to set how models is show when API is first rendered.
405    ///
406    /// The user can always switch the rendering for given model by clicking the `Model` and `Example Value` links.
407    ///
408    /// * `example` Makes example rendered first by default.
409    /// * `model` Makes model rendered first by default.
410    ///
411    /// # Examples
412    ///
413    /// ```rust
414    /// # use salvo_oapi::swagger_ui::Config;
415    /// let config = Config::new(["/api-docs/openapi.json"])
416    ///     .default_model_rendering(r#"["example"*, "model"]"#);
417    /// ```
418    #[must_use]
419    pub fn default_model_rendering<S: Into<String>>(mut self, default_model_rendering: S) -> Self {
420        self.default_model_rendering = Some(default_model_rendering.into());
421
422        self
423    }
424
425    /// Set to `true` to show request duration of _**'Try it out'**_ requests _**(in milliseconds)**_.
426    ///
427    /// Default value is `false`.
428    ///
429    /// # Examples
430    /// Enable request duration of the _**'Try it out'**_ requests.
431    /// ```rust
432    /// # use salvo_oapi::swagger_ui::Config;
433    /// let config = Config::new(["/api-docs/openapi.json"])
434    ///     .display_request_duration(true);
435    /// ```
436    #[must_use] pub fn display_request_duration(mut self, display_request_duration: bool) -> Self {
437        self.display_request_duration = Some(display_request_duration);
438
439        self
440    }
441
442    /// Add `doc_expansion` to control default expansion for operations and tags.
443    ///
444    /// * `list` Will expand only tags.
445    /// * `full` Will expand tags and operations.
446    /// * `none` Will expand nothing.
447    ///
448    /// # Examples
449    ///
450    /// ```rust
451    /// # use salvo_oapi::swagger_ui::Config;
452    /// let config = Config::new(["/api-docs/openapi.json"])
453    ///     .doc_expansion(r#"["list"*, "full", "none"]"#);
454    /// ```
455    #[must_use]
456    pub fn doc_expansion<S: Into<String>>(mut self, doc_expansion: S) -> Self {
457        self.doc_expansion = Some(doc_expansion.into());
458
459        self
460    }
461
462    /// Add `filter` to allow filtering of tagged operations.
463    ///
464    /// When enabled top bar will show and edit box that can be used to filter visible tagged operations.
465    /// Filter behaves case sensitive manner and matches anywhere inside the tag.
466    ///
467    /// Default value is `false`.
468    ///
469    /// # Examples
470    ///
471    /// Enable filtering.
472    /// ```rust
473    /// # use salvo_oapi::swagger_ui::Config;
474    /// let config = Config::new(["/api-docs/openapi.json"])
475    ///     .filter(true);
476    /// ```
477    #[must_use] pub fn filter(mut self, filter: bool) -> Self {
478        self.filter = Some(filter);
479
480        self
481    }
482
483    /// Add `max_displayed_tags` to restrict shown tagged operations.
484    ///
485    /// By default all operations are shown.
486    ///
487    /// # Examples
488    ///
489    /// Display only 4 operations.
490    /// ```rust
491    /// # use salvo_oapi::swagger_ui::Config;
492    /// let config = Config::new(["/api-docs/openapi.json"])
493    ///     .max_displayed_tags(4);
494    /// ```
495    #[must_use] pub fn max_displayed_tags(mut self, max_displayed_tags: usize) -> Self {
496        self.max_displayed_tags = Some(max_displayed_tags);
497
498        self
499    }
500
501    /// Set `show_extensions` to adjust whether vendor extension _**`(x-)`**_ fields and values
502    /// are shown for operations, parameters, responses and schemas.
503    ///
504    /// # Example
505    ///
506    /// Show vendor extensions.
507    /// ```rust
508    /// # use salvo_oapi::swagger_ui::Config;
509    /// let config = Config::new(["/api-docs/openapi.json"])
510    ///     .show_extensions(true);
511    /// ```
512    #[must_use] pub fn show_extensions(mut self, show_extensions: bool) -> Self {
513        self.show_extensions = Some(show_extensions);
514
515        self
516    }
517
518    /// Add `show_common_extensions` to define whether common extension
519    /// _**`(pattern, maxLength, minLength, maximum, minimum)`**_ fields and values are shown
520    /// for parameters.
521    ///
522    /// # Examples
523    ///
524    /// Show common extensions.
525    /// ```rust
526    /// # use salvo_oapi::swagger_ui::Config;
527    /// let config = Config::new(["/api-docs/openapi.json"])
528    ///     .show_common_extensions(true);
529    /// ```
530    #[must_use] pub fn show_common_extensions(mut self, show_common_extensions: bool) -> Self {
531        self.show_common_extensions = Some(show_common_extensions);
532
533        self
534    }
535
536    /// Add `try_it_out_enabled` to enable _**'Try it out'**_ section by default.
537    ///
538    /// Default value is `false`.
539    ///
540    /// # Examples
541    ///
542    /// Enable _**'Try it out'**_ section by default.
543    /// ```rust
544    /// # use salvo_oapi::swagger_ui::Config;
545    /// let config = Config::new(["/api-docs/openapi.json"])
546    ///     .try_it_out_enabled(true);
547    /// ```
548    #[must_use] pub fn try_it_out_enabled(mut self, try_it_out_enabled: bool) -> Self {
549        self.try_it_out_enabled = Some(try_it_out_enabled);
550
551        self
552    }
553
554    /// Set `request_snippets_enabled` to enable request snippets section.
555    ///
556    /// If disabled legacy curl snipped will be used.
557    ///
558    /// Default value is `false`.
559    ///
560    /// # Examples
561    ///
562    /// Enable request snippets section.
563    /// ```rust
564    /// # use salvo_oapi::swagger_ui::Config;
565    /// let config = Config::new(["/api-docs/openapi.json"])
566    ///     .request_snippets_enabled(true);
567    /// ```
568    #[must_use] pub fn request_snippets_enabled(mut self, request_snippets_enabled: bool) -> Self {
569        self.request_snippets_enabled = Some(request_snippets_enabled);
570
571        self
572    }
573
574    /// Add oauth redirect url.
575    ///
576    /// # Examples
577    ///
578    /// Add oauth redirect url.
579    /// ```rust
580    /// # use salvo_oapi::swagger_ui::Config;
581    /// let config = Config::new(["/api-docs/openapi.json"])
582    ///     .oauth2_redirect_url("http://my.oauth2.redirect.url");
583    /// ```
584    #[must_use]
585    pub fn oauth2_redirect_url<S: Into<String>>(mut self, oauth2_redirect_url: S) -> Self {
586        self.oauth2_redirect_url = Some(oauth2_redirect_url.into());
587
588        self
589    }
590
591    /// Add `show_mutated_request` to use request returned from `requestInterceptor`
592    /// to produce curl command in the UI. If set to `false` the request before `requestInterceptor`
593    /// was applied will be used.
594    ///
595    /// # Examples
596    ///
597    /// Use request after `requestInterceptor` to produce the curl command.
598    /// ```rust
599    /// # use salvo_oapi::swagger_ui::Config;
600    /// let config = Config::new(["/api-docs/openapi.json"])
601    ///     .show_mutated_request(true);
602    /// ```
603    #[must_use] pub fn show_mutated_request(mut self, show_mutated_request: bool) -> Self {
604        self.show_mutated_request = Some(show_mutated_request);
605
606        self
607    }
608
609    /// Add supported http methods for _**'Try it out'**_ operation.
610    ///
611    /// _**'Try it out'**_ will be enabled based on the given list of http methods when
612    /// the operation's http method is included within the list.
613    /// By giving an empty list will disable _**'Try it out'**_ from all operations but it will
614    /// **not** filter operations from the UI.
615    ///
616    /// By default all http operations are enabled.
617    ///
618    /// # Examples
619    ///
620    /// Set allowed http methods explicitly.
621    /// ```rust
622    /// # use salvo_oapi::swagger_ui::Config;
623    /// let config = Config::new(["/api-docs/openapi.json"])
624    ///     .supported_submit_methods(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
625    /// ```
626    ///
627    /// Allow _**'Try it out'**_ for only GET operations.
628    /// ```rust
629    /// # use salvo_oapi::swagger_ui::Config;
630    /// let config = Config::new(["/api-docs/openapi.json"])
631    ///     .supported_submit_methods(["get"]);
632    /// ```
633    #[must_use]
634    pub fn supported_submit_methods<I: IntoIterator<Item = S>, S: Into<String>>(
635        mut self,
636        supported_submit_methods: I,
637    ) -> Self {
638        self.supported_submit_methods = Some(
639            supported_submit_methods
640                .into_iter()
641                .map(|method| method.into())
642                .collect(),
643        );
644
645        self
646    }
647
648    /// Add validator url which is used to validate the Swagger spec.
649    ///
650    /// This can also be set to use locally deployed validator for example see
651    /// [Validator Badge](https://github.com/swagger-api/validator-badge) for more details.
652    ///
653    /// By default swagger.io's online validator _**`(https://validator.swagger.io/validator)`**_ will be used.
654    /// Setting this to `none` will disable the validator.
655    ///
656    /// # Examples
657    ///
658    /// Disable the validator.
659    /// ```rust
660    /// # use salvo_oapi::swagger_ui::Config;
661    /// let config = Config::new(["/api-docs/openapi.json"])
662    ///     .validator_url("none");
663    /// ```
664    #[must_use]
665    pub fn validator_url<S: Into<String>>(mut self, validator_url: S) -> Self {
666        self.validator_url = Some(validator_url.into());
667
668        self
669    }
670
671    /// Set `with_credentials` to enable passing credentials to CORS requests send by browser as defined
672    /// [fetch standards](https://fetch.spec.whatwg.org/#credentials).
673    ///
674    /// **Note**: that Swagger UI cannot currently set cookies cross-domain
675    /// (see [swagger-js#1163](https://github.com/swagger-api/swagger-js/issues/1163)) -
676    /// as a result, you will have to rely on browser-supplied cookies (which this setting enables sending)
677    /// that Swagger UI cannot control.
678    ///
679    /// # Examples
680    ///
681    /// Enable passing credentials to CORS requests.
682    /// ```rust
683    /// # use salvo_oapi::swagger_ui::Config;
684    /// let config = Config::new(["/api-docs/openapi.json"])
685    ///     .with_credentials(true);
686    /// ```
687    #[must_use] pub fn with_credentials(mut self, with_credentials: bool) -> Self {
688        self.with_credentials = Some(with_credentials);
689
690        self
691    }
692
693    /// Set to `true` to enable authorizations to be persisted throughout browser refresh and close.
694    ///
695    /// Default value is `false`.
696    ///
697    ///
698    /// # Examples
699    ///
700    /// Persists authorization throughout browser close and refresh.
701    /// ```rust
702    /// # use salvo_oapi::swagger_ui::Config;
703    /// let config = Config::new(["/api-docs/openapi.json"])
704    ///     .persist_authorization(true);
705    /// ```
706    #[must_use] pub fn persist_authorization(mut self, persist_authorization: bool) -> Self {
707        self.persist_authorization = Some(persist_authorization);
708
709        self
710    }
711}
712
713impl Default for Config<'_> {
714    fn default() -> Self {
715        Self {
716            config_url: Default::default(),
717            dom_id: Some("#swagger-ui".to_owned()),
718            url: Default::default(),
719            urls_primary_name: Default::default(),
720            urls: Default::default(),
721            query_config_enabled: Default::default(),
722            deep_linking: Some(true),
723            display_operation_id: Default::default(),
724            default_models_expand_depth: Default::default(),
725            default_model_expand_depth: Default::default(),
726            default_model_rendering: Default::default(),
727            display_request_duration: Default::default(),
728            doc_expansion: Default::default(),
729            filter: Default::default(),
730            max_displayed_tags: Default::default(),
731            show_extensions: Default::default(),
732            show_common_extensions: Default::default(),
733            try_it_out_enabled: Default::default(),
734            request_snippets_enabled: Default::default(),
735            oauth2_redirect_url: Default::default(),
736            show_mutated_request: Default::default(),
737            supported_submit_methods: Default::default(),
738            validator_url: Default::default(),
739            with_credentials: Default::default(),
740            persist_authorization: Default::default(),
741            oauth: Default::default(),
742            layout: SWAGGER_STANDALONE_LAYOUT,
743        }
744    }
745}
746
747impl<'a> From<&'a str> for Config<'a> {
748    fn from(s: &'a str) -> Self {
749        Self::new([s])
750    }
751}
752
753impl From<String> for Config<'_> {
754    fn from(s: String) -> Self {
755        Self::new([s])
756    }
757}