Skip to main content

dioxus_docs_kit/
config.rs

1//! Builder for constructing a `DocsRegistry`.
2
3use crate::registry::DocsRegistry;
4use std::collections::HashMap;
5
6/// Theme configuration for the documentation site.
7///
8/// Controls which DaisyUI theme(s) are applied and whether a toggle button is shown.
9#[derive(Clone, Debug)]
10pub struct ThemeConfig {
11    /// The default theme name (must match a DaisyUI theme defined in `tailwind.css`).
12    pub default_theme: String,
13    /// If set, enables a light/dark toggle button. Tuple is `(light_theme, dark_theme)`.
14    pub toggle_themes: Option<(String, String)>,
15    /// localStorage key used to persist the user's theme preference.
16    pub storage_key: String,
17}
18
19/// Builder for constructing a [`DocsRegistry`].
20///
21/// # Example
22///
23/// ```rust,ignore
24/// let registry = DocsConfig::new(nav_json, content_map)
25///     .with_openapi("api-reference", spec_yaml)
26///     .with_default_path("getting-started/introduction")
27///     .build();
28/// ```
29pub struct DocsConfig {
30    nav_json: String,
31    content_map: HashMap<&'static str, &'static str>,
32    openapi_specs: Vec<(String, String)>,
33    default_path: Option<String>,
34    api_group_name: Option<String>,
35    theme: Option<ThemeConfig>,
36}
37
38impl DocsConfig {
39    /// Create a new builder from a `_nav.json` string and a content map.
40    ///
41    /// The content map is typically generated by `build.rs` using `include_str!()`.
42    pub fn new(nav_json: &str, content_map: HashMap<&'static str, &'static str>) -> Self {
43        Self {
44            nav_json: nav_json.to_string(),
45            content_map,
46            openapi_specs: Vec::new(),
47            default_path: None,
48            api_group_name: None,
49            theme: None,
50        }
51    }
52
53    /// Add an OpenAPI specification.
54    ///
55    /// - `prefix`: The URL prefix for this spec's endpoints (e.g. "api-reference").
56    /// - `yaml`: The raw YAML string of the OpenAPI spec.
57    ///
58    /// The `prefix` must correspond to a nav group in `_nav.json` whose `"group"` value
59    /// matches [`Self::with_api_group_name`] (defaults to `"API Reference"`). The library
60    /// dynamically injects API endpoints into that group's sidebar — do **not** list
61    /// individual operation paths in the `"pages"` array of `_nav.json`.
62    pub fn with_openapi(mut self, prefix: &str, yaml: &str) -> Self {
63        self.openapi_specs
64            .push((prefix.to_string(), yaml.to_string()));
65        self
66    }
67
68    /// Set the default documentation path for redirects.
69    ///
70    /// Defaults to the first page in the first nav group if not set.
71    pub fn with_default_path(mut self, path: &str) -> Self {
72        self.default_path = Some(path.to_string());
73        self
74    }
75
76    /// Set the display name for the API Reference sidebar group.
77    ///
78    /// Defaults to `"API Reference"`. The value must match a `"group"` in `_nav.json`
79    /// so the library knows where to inject the API endpoint sidebar entries.
80    /// See [`Self::with_openapi`] for details.
81    pub fn with_api_group_name(mut self, name: &str) -> Self {
82        self.api_group_name = Some(name.to_string());
83        self
84    }
85
86    /// Set a single theme (no toggle button).
87    ///
88    /// The theme name must match a DaisyUI theme defined in the consumer's `tailwind.css`.
89    pub fn with_theme(mut self, theme: &str) -> Self {
90        self.theme = Some(ThemeConfig {
91            default_theme: theme.to_string(),
92            toggle_themes: None,
93            storage_key: "docs-theme".to_string(),
94        });
95        self
96    }
97
98    /// Enable a light/dark theme toggle.
99    ///
100    /// - `light`: Name of the light DaisyUI theme.
101    /// - `dark`: Name of the dark DaisyUI theme.
102    /// - `default`: Which of the two to use on first visit (`light` or `dark`).
103    pub fn with_theme_toggle(mut self, light: &str, dark: &str, default: &str) -> Self {
104        self.theme = Some(ThemeConfig {
105            default_theme: default.to_string(),
106            toggle_themes: Some((light.to_string(), dark.to_string())),
107            storage_key: "docs-theme".to_string(),
108        });
109        self
110    }
111
112    /// Build the [`DocsRegistry`].
113    ///
114    /// Parses all documents, builds the search index, and parses OpenAPI specs.
115    pub fn build(self) -> DocsRegistry {
116        DocsRegistry::from_config(self)
117    }
118
119    // Accessors for DocsRegistry::from_config
120    pub(crate) fn nav_json(&self) -> &str {
121        &self.nav_json
122    }
123
124    pub(crate) fn content_map(&self) -> &HashMap<&'static str, &'static str> {
125        &self.content_map
126    }
127
128    pub(crate) fn openapi_specs(&self) -> &[(String, String)] {
129        &self.openapi_specs
130    }
131
132    pub(crate) fn default_path_value(&self) -> Option<&str> {
133        self.default_path.as_deref()
134    }
135
136    pub(crate) fn api_group_name_value(&self) -> Option<&str> {
137        self.api_group_name.as_deref()
138    }
139
140    pub(crate) fn theme_config(&self) -> Option<&ThemeConfig> {
141        self.theme.as_ref()
142    }
143}