Skip to main content

wdl_doc/
config.rs

1//! Configuration type definitions.
2
3use std::path::PathBuf;
4
5use ammonia::Url;
6use wdl_analysis::Config as AnalysisConfig;
7
8/// External URLs related to the project.
9#[derive(Clone, Debug, Default)]
10pub struct ExternalUrls {
11    /// URL pointing to the project's homepage.
12    pub homepage: Option<Url>,
13    /// URL pointing to the project's GitHub repository.
14    pub github: Option<Url>,
15    /// URL pointing to the project's Slack workspace.
16    pub slack: Option<Url>,
17}
18
19/// Site-level SEO metadata embedded into each page's `<head>`.
20///
21/// Every field is optional; a given `<head>` tag is only emitted when its
22/// backing field is set.
23#[derive(Clone, Debug, Default)]
24pub struct Seo {
25    /// Site title. When set, each page's `<title>` becomes
26    /// `"<page> | <title>"` and drives `og:site_name`.
27    pub title: Option<String>,
28    /// Default page description (`<meta name="description">`, `og:description`,
29    /// `twitter:description`).
30    pub description: Option<String>,
31    /// Content author (`<meta name="author">`).
32    pub author: Option<String>,
33    /// Keywords (`<meta name="keywords">`).
34    pub keywords: Vec<String>,
35    /// Absolute site base URL used to build per-page `<link rel="canonical">`
36    /// and `og:url` values.
37    pub base_url: Option<Url>,
38    /// Social-preview image URL (`og:image`, `twitter:image`).
39    pub image_url: Option<Url>,
40    /// Open Graph locale (`og:locale`); defaults to `en_US` when unset.
41    pub locale: Option<String>,
42    /// Twitter handle, including the leading `@` (`twitter:site`,
43    /// `twitter:creator`).
44    pub twitter_handle: Option<String>,
45    /// Robots directive (`<meta name="robots">`, e.g. `index, follow`).
46    pub robots: Option<String>,
47    /// Browser theme color (`<meta name="theme-color">`).
48    pub theme_color: Option<String>,
49}
50
51/// Additional HTML to embed into each generated page.
52#[derive(Debug, Default)]
53pub struct AdditionalHtml {
54    /// Embed the contents immediately before the closing `</head>` tag.
55    head: Option<String>,
56    /// Embed the contents immediately after the opening `<body>` tag.
57    body_open: Option<String>,
58    /// Embed the contents immediately before the closing `</body>` tag.
59    body_close: Option<String>,
60}
61
62impl AdditionalHtml {
63    /// Create a new [`AdditionalHtml`] struct.
64    pub fn new(
65        head: Option<String>,
66        body_open: Option<String>,
67        body_close: Option<String>,
68    ) -> Self {
69        Self {
70            head,
71            body_open,
72            body_close,
73        }
74    }
75
76    /// Get the HTML to add to the head.
77    pub fn head(&self) -> Option<&str> {
78        self.head.as_deref()
79    }
80
81    /// Get the HTML to add to the body open.
82    pub fn body_open(&self) -> Option<&str> {
83        self.body_open.as_deref()
84    }
85
86    /// Get the HTML to add to the body close.
87    pub fn body_close(&self) -> Option<&str> {
88        self.body_close.as_deref()
89    }
90}
91
92/// Configuration for documentation generation.
93#[derive(Debug)]
94pub struct Config {
95    /// Configuration to use for analysis.
96    pub(crate) analysis_config: AnalysisConfig,
97    /// WDL workspace that should be documented.
98    pub(crate) workspace: PathBuf,
99    /// Output location for the documentation.
100    pub(crate) output_dir: PathBuf,
101    /// An optional markdown file to embed in the root index page.
102    pub(crate) index_page: Option<PathBuf>,
103    /// Analyze the documents without producing an output.
104    pub(crate) check: bool,
105    /// Initialize pages in light mode instead of the default dark mode.
106    pub(crate) init_light_mode: bool,
107    /// An optional custom theme directory.
108    pub(crate) custom_theme: Option<PathBuf>,
109    /// An optional custom logo to embed in the left sidebar.
110    pub(crate) custom_logo: Option<PathBuf>,
111    /// External URLs related to the project.
112    pub(crate) external_urls: ExternalUrls,
113    /// An optional alternate (light mode) custom logo to embed in the left
114    /// sidebar.
115    pub(crate) alt_logo: Option<PathBuf>,
116    /// Optional HTML to embed in each page.
117    pub(crate) additional_html: AdditionalHtml,
118    /// Site-level SEO metadata embedded into each page's `<head>`.
119    pub(crate) seo: Seo,
120    /// (**EXPERIMENTAL**) Enable support for documentation comments.
121    pub(crate) enable_doc_comments: bool,
122}
123
124impl Config {
125    /// Create a new documentation configuration.
126    pub fn new(
127        analysis_config: AnalysisConfig,
128        workspace: impl Into<PathBuf>,
129        output_dir: impl Into<PathBuf>,
130    ) -> Self {
131        Self {
132            analysis_config,
133            workspace: workspace.into(),
134            output_dir: output_dir.into(),
135            index_page: None,
136            check: false,
137            init_light_mode: false,
138            custom_theme: None,
139            custom_logo: None,
140            external_urls: ExternalUrls::default(),
141            alt_logo: None,
142            additional_html: AdditionalHtml::default(),
143            seo: Seo::default(),
144            enable_doc_comments: false,
145        }
146    }
147
148    /// Overwrite the config's index page with the new value.
149    pub fn index_page(mut self, index_page: Option<PathBuf>) -> Self {
150        self.index_page = index_page;
151        self
152    }
153
154    /// Overwrite the config's check default with the new value.
155    pub fn check(mut self, check: bool) -> Self {
156        self.check = check;
157        self
158    }
159
160    /// Overwrite the config's light mode default with the new value.
161    pub fn init_light_mode(mut self, init_light_mode: bool) -> Self {
162        self.init_light_mode = init_light_mode;
163        self
164    }
165
166    /// Overwrite the config's custom theme with the new value.
167    pub fn custom_theme(mut self, custom_theme: Option<PathBuf>) -> Self {
168        self.custom_theme = custom_theme;
169        self
170    }
171
172    /// Overwrite the config's custom logo with the new value.
173    pub fn custom_logo(mut self, custom_logo: Option<PathBuf>) -> Self {
174        self.custom_logo = custom_logo;
175        self
176    }
177
178    /// Overwrite the config's external URLs with the new value.
179    pub fn external_urls(mut self, external_urls: ExternalUrls) -> Self {
180        self.external_urls = external_urls;
181        self
182    }
183
184    /// Overwrite the config's alternate logo with the new value.
185    pub fn alt_logo(mut self, alt_logo: Option<PathBuf>) -> Self {
186        self.alt_logo = alt_logo;
187        self
188    }
189
190    /// Overwrite the config's additional HTML with the new value.
191    pub fn additional_html(mut self, additional_html: AdditionalHtml) -> Self {
192        self.additional_html = additional_html;
193        self
194    }
195
196    /// Overwrite the config's SEO metadata with the new value.
197    pub fn seo(mut self, seo: Seo) -> Self {
198        self.seo = seo;
199        self
200    }
201
202    /// Enable support for documentation comments.
203    ///
204    /// NOTE: This is an experimental option, and will be removed in a future
205    /// major release.
206    ///
207    /// For more information, see the pre-RFC discussion
208    /// [here](https://github.com/openwdl/wdl/issues/757).
209    pub fn enable_doc_comments(mut self, enable_doc_comments: bool) -> Self {
210        self.enable_doc_comments = enable_doc_comments;
211        self
212    }
213}