Skip to content

Commit 55ea1ea

Browse files
authored
Add generic types for TryFrom<BTreeMap<K, V>> impl (#714)
1 parent 91b156a commit 55ea1ea

File tree

3 files changed

+106
-19
lines changed

3 files changed

+106
-19
lines changed

src/kvp/annotation/mod.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,27 @@ impl Annotation {
141141
#[derive(Clone, Debug, Default)]
142142
pub struct Annotations(KeyValuePairs<AnnotationValue>);
143143

144-
impl TryFrom<BTreeMap<String, String>> for Annotations {
144+
impl<K, V> TryFrom<BTreeMap<K, V>> for Annotations
145+
where
146+
K: AsRef<str>,
147+
V: AsRef<str>,
148+
{
149+
type Error = AnnotationError;
150+
151+
fn try_from(value: BTreeMap<K, V>) -> Result<Self, Self::Error> {
152+
let kvps = KeyValuePairs::try_from(value)?;
153+
Ok(Self(kvps))
154+
}
155+
}
156+
157+
impl<K, V> TryFrom<&BTreeMap<K, V>> for Annotations
158+
where
159+
K: AsRef<str>,
160+
V: AsRef<str>,
161+
{
145162
type Error = AnnotationError;
146163

147-
fn try_from(value: BTreeMap<String, String>) -> Result<Self, Self::Error> {
164+
fn try_from(value: &BTreeMap<K, V>) -> Result<Self, Self::Error> {
148165
let kvps = KeyValuePairs::try_from(value)?;
149166
Ok(Self(kvps))
150167
}

src/kvp/label/mod.rs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,28 @@ impl Label {
142142
#[derive(Clone, Debug, Default)]
143143
pub struct Labels(KeyValuePairs<LabelValue>);
144144

145-
impl TryFrom<BTreeMap<String, String>> for Labels {
145+
impl<K, V> TryFrom<BTreeMap<K, V>> for Labels
146+
where
147+
K: AsRef<str>,
148+
V: AsRef<str>,
149+
{
146150
type Error = LabelError;
147151

148-
fn try_from(value: BTreeMap<String, String>) -> Result<Self, Self::Error> {
149-
let kvps = KeyValuePairs::try_from(value)?;
152+
fn try_from(map: BTreeMap<K, V>) -> Result<Self, Self::Error> {
153+
let kvps = KeyValuePairs::try_from(map)?;
154+
Ok(Self(kvps))
155+
}
156+
}
157+
158+
impl<K, V> TryFrom<&BTreeMap<K, V>> for Labels
159+
where
160+
K: AsRef<str>,
161+
V: AsRef<str>,
162+
{
163+
type Error = LabelError;
164+
165+
fn try_from(map: &BTreeMap<K, V>) -> Result<Self, Self::Error> {
166+
let kvps = KeyValuePairs::try_from(map)?;
150167
Ok(Self(kvps))
151168
}
152169
}

src/kvp/mod.rs

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -145,18 +145,75 @@ pub enum KeyValuePairsError {
145145
}
146146

147147
/// A validated set/list of Kubernetes key/value pairs.
148+
///
149+
/// It implements various traits which allows conversion from and to different
150+
/// data types. Traits to construct [`KeyValuePairs`] from other data types are:
151+
///
152+
/// - `TryFrom<&BTreeMap<String, String>>`
153+
/// - `TryFrom<BTreeMap<String, String>>`
154+
/// - `FromIterator<KeyValuePair<T>>`
155+
/// - `TryFrom<[(K, V); N]>`
156+
///
157+
/// Traits to convert [`KeyValuePairs`] into a different data type are:
158+
///
159+
/// - `From<KeyValuePairs<T>> for BTreeMap<String, String>`
160+
///
161+
/// ## Examples
162+
///
163+
/// ### Converting a BTreeMap into a list of labels
164+
///
165+
/// ```
166+
/// # use std::collections::BTreeMap;
167+
/// # use stackable_operator::kvp::Labels;
168+
/// let map = BTreeMap::from([
169+
/// ("stackable.tech/managed-by", "stackablectl"),
170+
/// ("stackable.tech/vendor", "Stackable"),
171+
/// ]);
172+
///
173+
/// let labels = Labels::try_from(map).unwrap();
174+
/// ```
175+
///
176+
/// ### Creating a list of labels from an array
177+
///
178+
/// ```
179+
/// # use stackable_operator::kvp::Labels;
180+
/// let labels = Labels::try_from([
181+
/// ("stackable.tech/managed-by", "stackablectl"),
182+
/// ("stackable.tech/vendor", "Stackable"),
183+
/// ]).unwrap();
184+
/// ```
148185
#[derive(Clone, Debug, Default)]
149186
pub struct KeyValuePairs<T: Value>(BTreeSet<KeyValuePair<T>>);
150187

151-
impl<T> TryFrom<BTreeMap<String, String>> for KeyValuePairs<T>
188+
impl<K, V, T> TryFrom<BTreeMap<K, V>> for KeyValuePairs<T>
189+
where
190+
K: AsRef<str>,
191+
V: AsRef<str>,
192+
T: Value,
193+
{
194+
type Error = KeyValuePairError<T::Error>;
195+
196+
fn try_from(map: BTreeMap<K, V>) -> Result<Self, Self::Error> {
197+
let pairs = map
198+
.iter()
199+
.map(KeyValuePair::try_from)
200+
.collect::<Result<BTreeSet<_>, KeyValuePairError<T::Error>>>()?;
201+
202+
Ok(Self(pairs))
203+
}
204+
}
205+
206+
impl<K, V, T> TryFrom<&BTreeMap<K, V>> for KeyValuePairs<T>
152207
where
208+
K: AsRef<str>,
209+
V: AsRef<str>,
153210
T: Value,
154211
{
155212
type Error = KeyValuePairError<T::Error>;
156213

157-
fn try_from(map: BTreeMap<String, String>) -> Result<Self, Self::Error> {
214+
fn try_from(map: &BTreeMap<K, V>) -> Result<Self, Self::Error> {
158215
let pairs = map
159-
.into_iter()
216+
.iter()
160217
.map(KeyValuePair::try_from)
161218
.collect::<Result<BTreeSet<_>, KeyValuePairError<T::Error>>>()?;
162219

@@ -357,11 +414,8 @@ mod test {
357414
#[test]
358415
fn labels_try_from_map() {
359416
let map = BTreeMap::from([
360-
("stackable.tech/vendor".to_string(), "Stackable".to_string()),
361-
(
362-
"stackable.tech/managed-by".to_string(),
363-
"stackablectl".to_string(),
364-
),
417+
("stackable.tech/managed-by", "stackablectl"),
418+
("stackable.tech/vendor", "Stackable"),
365419
]);
366420

367421
let labels = Labels::try_from(map).unwrap();
@@ -370,14 +424,13 @@ mod test {
370424

371425
#[test]
372426
fn labels_into_map() {
373-
let pairs = BTreeSet::from([
374-
KeyValuePair::try_from(("stackable.tech/managed-by", "stackablectl")).unwrap(),
375-
KeyValuePair::try_from(("stackable.tech/vendor", "Stackable")).unwrap(),
376-
]);
427+
let labels = Labels::try_from([
428+
("stackable.tech/managed-by", "stackablectl"),
429+
("stackable.tech/vendor", "Stackable"),
430+
])
431+
.unwrap();
377432

378-
let labels = Labels::new_with(pairs);
379433
let map: BTreeMap<String, String> = labels.into();
380-
381434
assert_eq!(map.len(), 2);
382435
}
383436

0 commit comments

Comments
 (0)