Skip to main content

configbuilder_pattern_loader/
feature_summary.rs

1use std::fmt;
2
3use crate::{FeatureRecord, OverrideSource};
4
5/// A point-in-time snapshot of every feature loaded through the registry facade.
6pub struct FeatureSummary {
7    pub(crate) records: Vec<FeatureRecord>,
8}
9
10impl FeatureSummary {
11    pub(crate) fn enabled_count(&self) -> usize {
12        self.records.iter().filter(|r| r.enabled).count()
13    }
14
15    pub(crate) fn disabled_count(&self) -> usize {
16        self.records.iter().filter(|r| !r.enabled).count()
17    }
18
19    pub(crate) fn total_count(&self) -> usize {
20        self.records.len()
21    }
22
23    pub(crate) fn all_enabled(&self) -> bool {
24        self.records.iter().all(|r| r.enabled)
25    }
26}
27
28impl crate::FeatureSummaryOps for FeatureSummary {
29    fn enabled_count(&self) -> usize {
30        FeatureSummary::enabled_count(self)
31    }
32
33    fn disabled_count(&self) -> usize {
34        FeatureSummary::disabled_count(self)
35    }
36
37    fn total_count(&self) -> usize {
38        FeatureSummary::total_count(self)
39    }
40
41    fn all_enabled(&self) -> bool {
42        FeatureSummary::all_enabled(self)
43    }
44}
45
46impl fmt::Display for FeatureSummary {
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        writeln!(
49            f,
50            "features: {}/{} enabled",
51            self.enabled_count(),
52            self.total_count()
53        )?;
54        for record in &self.records {
55            let status = if record.enabled { "ON " } else { "OFF" };
56            let override_note = match &record.override_source {
57                None => String::new(),
58                Some(OverrideSource::ExplicitTomlFlag) => " [disabled by enabled=false]".to_owned(),
59                Some(OverrideSource::EnvVar { var_name, value }) => {
60                    format!(" [env {var_name}={value}]")
61                }
62                Some(OverrideSource::ValidationError { reason }) => {
63                    format!(" [DEGRADED: {reason}]")
64                }
65            };
66            let description = if record.metadata.description.is_empty() {
67                String::new()
68            } else {
69                format!("  — {}", record.metadata.description)
70            };
71            let owner = if record.metadata.owner.is_empty() {
72                String::new()
73            } else {
74                format!(" (owner: {})", record.metadata.owner)
75            };
76            let deprecated = match record.metadata.deprecated_since {
77                None => String::new(),
78                Some(v) => format!(" [DEPRECATED since {v}]"),
79            };
80            writeln!(
81                f,
82                "  [{status}] {}{override_note}{description}{owner}{deprecated}",
83                record.section_name
84            )?;
85        }
86        Ok(())
87    }
88}