Skip to content

Commit d868708

Browse files
committed
Added config::merge::chainable_merge() (#397)
1 parent 826e381 commit d868708

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44

55
## [Unreleased]
66

7+
### Added
8+
9+
- Added `config::merge::chainable_merge()` ([#397]).
10+
11+
[#397]: https://github.com/stackabletech/operator-rs/pull/397
12+
713
## [0.19.0] - 2022-05-05
814

915
### Changed

src/config/merge.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,39 @@ impl<K: Hash + Eq + Clone, V: Merge + Clone> Merge for HashMap<K, V> {
8181
}
8282
}
8383

84+
/// Moving version of [`Merge::merge`], to produce slightly nicer test output
85+
pub fn merge<T: Merge>(mut overrides: T, defaults: &T) -> T {
86+
overrides.merge(defaults);
87+
overrides
88+
}
89+
90+
/// Composable version of [`Merge::merge`] that allows reducing a sequence of `Option<mut& T>`.
91+
///
92+
/// Example:
93+
///
94+
/// ```
95+
/// use stackable_operator::config::merge::{Merge, chainable_merge};
96+
/// #[derive(Clone, Default, Merge, PartialEq)]
97+
/// struct MyConfig {
98+
/// field: Option<i32>,
99+
/// }
100+
///
101+
/// let mut c0 = None;
102+
/// let mut c1 = Some(MyConfig { field: Some(23) });
103+
/// let mut c2 = Some(MyConfig { field: Some(7) });
104+
///
105+
/// let merged = [c0.as_mut(), c1.as_mut(), c2.as_mut()]
106+
/// .into_iter()
107+
/// .flatten()
108+
/// .reduce(|old, new| chainable_merge(new, old));
109+
///
110+
/// assert_eq!(7, merged.unwrap().field.unwrap());
111+
/// ```
112+
pub fn chainable_merge<'a, T: Merge + Clone>(this: &'a mut T, defaults: &T) -> &'a mut T {
113+
this.merge(defaults);
114+
this
115+
}
116+
84117
/// A marker trait for types that are merged atomically (as one single value) rather than
85118
/// trying to merge each field individually
86119
pub trait Atomic: Clone {}
@@ -113,13 +146,7 @@ impl<T: Atomic> Merge for Option<T> {
113146
mod tests {
114147
use std::collections::{BTreeMap, HashMap};
115148

116-
use super::Merge;
117-
118-
/// Moving version of [`Merge::merge`], to produce slightly nicer test output
119-
fn merge<T: Merge>(mut overrides: T, defaults: &T) -> T {
120-
overrides.merge(defaults);
121-
overrides
122-
}
149+
use super::{merge, Merge};
123150

124151
#[derive(Debug, PartialEq, Eq, Clone)]
125152
struct Accumulator(u8);

0 commit comments

Comments
 (0)