Skip to main content

dbc_codegen/
feature_config.rs

1use std::fmt::Display;
2use std::io::Write;
3
4use anyhow::{Error, Result};
5
6/// Configuration for including features in the code generator.
7///
8/// e.g. [Debug] impls for generated types.
9#[derive(Default)]
10pub enum FeatureConfig<'a> {
11    /// Generate code for this feature.
12    Always,
13
14    /// Generate code behind `#[cfg(feature = ...)]`
15    Gated(&'a str),
16
17    /// Don't generate code for this feature.
18    #[default]
19    Never,
20}
21
22impl FeatureConfig<'_> {
23    pub(crate) fn fmt_attr(&self, w: &mut impl Write, attr: impl Display) -> Result<()> {
24        match self {
25            FeatureConfig::Always => writeln!(w, "#[{attr}]")?,
26            FeatureConfig::Gated(gate) => writeln!(w, "#[cfg_attr(feature = {gate:?}, {attr})]")?,
27            FeatureConfig::Never => {}
28        }
29        Ok(())
30    }
31
32    pub(crate) fn fmt_cfg<W: Write, E: Into<Error>>(
33        &self,
34        mut w: W,
35        f: impl FnOnce(W) -> Result<(), E>,
36    ) -> Result<()> {
37        match self {
38            // If config is Never, return immediately without calling `f`
39            FeatureConfig::Never => return Ok(()),
40            // If config is Gated, prepend `f` with a cfg guard
41            FeatureConfig::Gated(gate) => {
42                writeln!(w, "#[cfg(feature = {gate:?})]")?;
43            }
44            // Otherwise, just call `f`
45            FeatureConfig::Always => {}
46        }
47
48        f(w).map_err(Into::into)
49    }
50}