configbuilder_pattern_loader/
feature_summary.rs1use std::fmt;
2
3use crate::{FeatureRecord, OverrideSource};
4
5pub 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}