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}