cli_xtask/
config.rs

1//! Data structures for workflow configuration.
2
3mod dist;
4mod dist_package;
5mod dist_target;
6
7use eyre::eyre;
8
9pub use self::{
10    dist::{DistConfig, DistConfigBuilder},
11    dist_package::{DistPackageConfig, DistPackageConfigBuilder},
12    dist_target::{DistTargetConfig, DistTargetConfigBuilder},
13};
14use crate::Result;
15
16/// Configures and constructs [`Config`].
17///
18/// # Examples
19///
20/// ```rust
21/// # fn main() -> cli_xtask::Result<()> {
22/// use cli_xtask::{
23///     config::{ConfigBuilder, DistConfigBuilder},
24///     workspace,
25/// };
26///
27/// let workspace = workspace::current();
28/// let dist_config = DistConfigBuilder::new("app-dist", workspace).build()?;
29/// let config = ConfigBuilder::new().dist(dist_config).build()?;
30/// # Ok(())
31/// # }
32/// ```
33#[derive(Debug, Default)]
34pub struct ConfigBuilder<'a> {
35    dist: Option<DistConfig<'a>>,
36}
37
38impl<'a> ConfigBuilder<'a> {
39    /// Creates a new `ConfigBuilder`.
40    pub fn new() -> Self {
41        Self::default()
42    }
43
44    /// Adds a [`DistConfig`] to the builder.
45    pub fn dist(mut self, dist: DistConfig<'a>) -> Self {
46        self.dist = Some(dist);
47        self
48    }
49
50    /// Builds a [`Config`] from the current configuration.
51    ///
52    /// # Errors
53    ///
54    /// Returns an error if the [`Config`] cannot be built.
55    pub fn build(self) -> Result<Config<'a>> {
56        Ok(Config { dist: self.dist })
57    }
58}
59
60/// Top-level configuration for cargo xtask workflow.
61///
62/// This struct is build from [`ConfigBuilder`].
63///
64/// # Examples
65///
66/// Creates an empty `Config`.
67///
68/// ```rust
69/// # fn main() -> cli_xtask::Result<()> {
70/// use cli_xtask::config::Config;
71/// let config = Config::new();
72/// assert!(config.dist().is_err());
73/// # Ok(())
74/// # }
75/// ```
76///
77/// Creates a `Config` with a [`DistConfig`].
78///
79/// ```
80/// # fn main() -> cli_xtask::Result<()> {
81/// use cli_xtask::{
82///     config::{ConfigBuilder, DistConfigBuilder},
83///     workspace,
84/// };
85///
86/// let workspace = workspace::current();
87/// let dist_config = DistConfigBuilder::new("app-dist", workspace).build()?;
88/// let config = ConfigBuilder::new().dist(dist_config).build()?;
89/// assert!(config.dist().is_ok());
90/// # Ok(())
91/// # }
92/// ```
93#[derive(Debug, Default)]
94pub struct Config<'a> {
95    dist: Option<DistConfig<'a>>,
96}
97
98impl<'a> Config<'a> {
99    /// Creates an empty `Config`.
100    pub fn new() -> Self {
101        Self::default()
102    }
103
104    /// Returns the [`DistConfig`] if one was configured.
105    ///
106    /// # Errors
107    ///
108    /// Returns an error if the [`DistConfig`] is not set.
109    pub fn dist(&self) -> Result<&DistConfig<'a>> {
110        self.dist
111            .as_ref()
112            .ok_or_else(|| eyre!("no dist configuration set"))
113    }
114}