use deepmerge::{DeepMerge, DeepMergeDefault, ComposedPolicy, DefaultPolicy};
#[cfg(feature = "std")]
use deepmerge::{vec_append_with_dedupe, vec_prepend_with_dedupe};
#[derive(Clone)]
struct DedupePolicy {
dedupe: bool,
}
impl deepmerge::Policy for DedupePolicy {
fn sequence_dedupe(&self) -> bool {
self.dedupe
}
}
#[test]
fn test_sequence_dedupe_policy_default() {
let policy = DefaultPolicy;
let mut vec1 = vec![1, 2, 2, 3];
let vec2 = vec![3, 4, 4, 5];
vec1.merge_with_policy(vec2, &policy);
assert_eq!(vec1, vec![1, 2, 2, 3, 3, 4, 4, 5]);
}
#[test]
fn test_sequence_dedupe_policy_enabled() {
let policy = ComposedPolicy::new(DefaultPolicy)
.with_sequence_dedupe(true);
let mut vec1 = vec![1, 2, 2, 3];
let vec2 = vec![3, 4, 4, 5];
vec1.merge_with_policy(vec2, &policy);
assert_eq!(vec1, vec![1, 2, 2, 3, 3, 4, 4, 5]);
}
#[test]
#[cfg(feature = "std")]
fn test_explicit_dedupe_functions() {
let mut vec1 = vec![1, 2, 2, 3];
let vec2 = vec![3, 4, 4, 5];
vec_append_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec![1, 2, 3, 4, 5]);
let mut vec1 = vec![1, 2, 2, 3];
let vec2 = vec![3, 4, 4, 5];
vec_prepend_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec![3, 4, 5, 1, 2]);
}
#[test]
#[cfg(feature = "std")]
fn test_dedupe_with_strings() {
let mut vec1 = vec!["a".to_string(), "b".to_string(), "b".to_string()];
let vec2 = vec!["b".to_string(), "c".to_string(), "c".to_string()];
vec_append_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec!["a".to_string(), "b".to_string(), "c".to_string()]);
}
#[test]
#[cfg(feature = "std")]
fn test_dedupe_preserves_order() {
let mut vec1 = vec![3, 1, 2, 1];
let vec2 = vec![2, 4, 3, 4];
vec_append_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec![3, 1, 2, 4]);
}
#[test]
#[cfg(feature = "std")]
fn test_dedupe_empty_cases() {
let mut vec1: Vec<i32> = vec![];
let vec2 = vec![1, 2, 2, 3];
vec_append_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec![1, 2, 3]);
let mut vec1 = vec![1, 2, 2, 3];
let vec2: Vec<i32> = vec![];
vec_append_with_dedupe(&mut vec1, vec2);
assert_eq!(vec1, vec![1, 2, 3]); }
#[cfg(feature = "std")]
#[derive(deepmerge::DeepMerge, Debug, Clone, PartialEq)]
#[merge(policy(sequence_dedupe = true))]
struct ConfigWithDedupe {
tags: Vec<String>,
values: Vec<i32>,
}
#[test]
#[cfg(feature = "std")]
fn test_derive_with_sequence_dedupe() {
let mut config = ConfigWithDedupe {
tags: vec!["rust".to_string(), "web".to_string(), "web".to_string()],
values: vec![1, 2, 2, 3],
};
let update = ConfigWithDedupe {
tags: vec!["api".to_string(), "rust".to_string()],
values: vec![3, 4, 4],
};
config.merge(update);
assert_eq!(config.tags, vec![
"rust".to_string(),
"web".to_string(),
"web".to_string(),
"api".to_string(),
"rust".to_string()
]);
assert_eq!(config.values, vec![1, 2, 2, 3, 3, 4, 4]);
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
struct OrdOnlyType {
value: i32,
}
#[test]
fn test_dedupe_with_ord_only_types() {
let policy = ComposedPolicy::new(DefaultPolicy)
.with_sequence_dedupe(true);
let mut vec1 = vec![
OrdOnlyType { value: 1 },
OrdOnlyType { value: 2 },
OrdOnlyType { value: 2 },
];
let vec2 = vec![
OrdOnlyType { value: 3 },
OrdOnlyType { value: 3 },
];
vec1.merge_with_policy(vec2, &policy);
assert_eq!(vec1.len(), 5);
}