chie_shared/config/
merge.rs

1//! Configuration merge utilities
2
3use super::{FeatureFlags, RetryConfig};
4
5/// Configuration merge utilities for combining configurations with priority
6///
7/// This utility provides methods to merge two configuration instances with various
8/// merge strategies. Useful for layered configuration systems where settings can come
9/// from multiple sources (defaults → file → environment → CLI).
10///
11/// # Examples
12///
13/// ```
14/// use chie_shared::{ConfigMerge, FeatureFlags};
15///
16/// // OR merge: feature enabled if enabled in either config
17/// let base = FeatureFlags {
18///     experimental: true,
19///     beta: false,
20///     ..FeatureFlags::none()
21/// };
22/// let override_flags = FeatureFlags {
23///     experimental: false,
24///     beta: true,
25///     ..FeatureFlags::none()
26/// };
27///
28/// let merged = ConfigMerge::feature_flags(&base, &override_flags, false);
29/// assert!(merged.experimental); // true from base
30/// assert!(merged.beta);         // true from override
31/// ```
32pub struct ConfigMerge;
33
34impl ConfigMerge {
35    /// Merge two `RetryConfig` instances with override semantics
36    ///
37    /// The `override_config` takes priority over `base_config` for all fields.
38    /// This is useful for layered configuration where CLI args override file config, etc.
39    ///
40    /// # Examples
41    ///
42    /// ```
43    /// use chie_shared::{ConfigMerge, RetryConfig};
44    ///
45    /// let base = RetryConfig {
46    ///     max_attempts: 5,
47    ///     initial_backoff_ms: 200,
48    ///     ..RetryConfig::default()
49    /// };
50    ///
51    /// let override_config = RetryConfig {
52    ///     max_attempts: 10,
53    ///     ..RetryConfig::default()
54    /// };
55    ///
56    /// let merged = ConfigMerge::retry_config(&base, &override_config);
57    /// assert_eq!(merged.max_attempts, 10); // From override
58    /// ```
59    #[must_use]
60    pub fn retry_config(_base: &RetryConfig, override_config: &RetryConfig) -> RetryConfig {
61        // Complete override - all fields from override_config
62        override_config.clone()
63    }
64
65    /// Merge two `FeatureFlags` instances
66    ///
67    /// If `override_all` is true, the `override_flags` completely replaces `base_flags`.
68    /// If `override_all` is false, features are merged with OR logic (a feature is enabled
69    /// if it's enabled in either base or override).
70    ///
71    /// # Examples
72    ///
73    /// ```
74    /// use chie_shared::{ConfigMerge, FeatureFlags};
75    ///
76    /// let base = FeatureFlags::all();
77    /// let override_flags = FeatureFlags::none();
78    ///
79    /// // Complete override - all features disabled
80    /// let merged = ConfigMerge::feature_flags(&base, &override_flags, true);
81    /// assert!(!merged.experimental);
82    /// assert!(!merged.beta);
83    ///
84    /// // OR merge - features enabled if enabled in either
85    /// let merged = ConfigMerge::feature_flags(&base, &override_flags, false);
86    /// assert!(merged.experimental); // Enabled in base
87    /// assert!(merged.beta);         // Enabled in base
88    /// ```
89    #[must_use]
90    pub fn feature_flags(
91        base: &FeatureFlags,
92        override_flags: &FeatureFlags,
93        override_all: bool,
94    ) -> FeatureFlags {
95        if override_all {
96            // Complete override
97            override_flags.clone()
98        } else {
99            // OR merge - feature is enabled if enabled in either config
100            FeatureFlags {
101                experimental: base.experimental || override_flags.experimental,
102                beta: base.beta || override_flags.beta,
103                enhanced_telemetry: base.enhanced_telemetry || override_flags.enhanced_telemetry,
104                performance_profiling: base.performance_profiling
105                    || override_flags.performance_profiling,
106                debug_mode: base.debug_mode || override_flags.debug_mode,
107                compression_optimization: base.compression_optimization
108                    || override_flags.compression_optimization,
109                adaptive_retry: base.adaptive_retry || override_flags.adaptive_retry,
110            }
111        }
112    }
113}