diff --git a/library/alloc/src/collections/btree/map/tests.rs b/library/alloc/src/collections/btree/map/tests.rs index 79879d31d3df..085834df9a68 100644 --- a/library/alloc/src/collections/btree/map/tests.rs +++ b/library/alloc/src/collections/btree/map/tests.rs @@ -11,7 +11,7 @@ use crate::fmt::Debug; use crate::rc::Rc; use crate::string::{String, ToString}; use crate::testing::crash_test::{CrashTestDummy, Panic}; -use crate::testing::ord_chaos::{Cyclic3, Governed, Governor}; +use crate::testing::ord_chaos::{Cyclic3, Governed, Governor, IdBased}; use crate::testing::rng::DeterministicRng; // Minimum number of elements to insert, to guarantee a tree with 2 levels, @@ -2587,3 +2587,31 @@ fn cursor_peek_prev_agrees_with_cursor_mut() { let prev = cursor.peek_prev(); assert_matches!(prev, Some((&3, _))); } + +#[test] +fn test_id_based_insert() { + let mut lhs = BTreeMap::new(); + let mut rhs = BTreeMap::new(); + + lhs.insert(IdBased { id: 0, name: "lhs_k".to_string() }, "lhs_v".to_string()); + rhs.insert(IdBased { id: 0, name: "rhs_k".to_string() }, "rhs_v".to_string()); + + for (k, v) in rhs.into_iter() { + lhs.insert(k, v); + } + + assert_eq!(lhs.pop_first().unwrap().0.name, "lhs_k".to_string()); +} + +#[test] +fn test_id_based_append() { + let mut lhs = BTreeMap::new(); + let mut rhs = BTreeMap::new(); + + lhs.insert(IdBased { id: 0, name: "lhs_k".to_string() }, "lhs_v".to_string()); + rhs.insert(IdBased { id: 0, name: "rhs_k".to_string() }, "rhs_v".to_string()); + + lhs.append(&mut rhs); + + assert_eq!(lhs.pop_first().unwrap().0.name, "lhs_k".to_string()); +} diff --git a/library/alloctests/testing/ord_chaos.rs b/library/alloctests/testing/ord_chaos.rs index 55e1ae5e3dea..f90ba1c69921 100644 --- a/library/alloctests/testing/ord_chaos.rs +++ b/library/alloctests/testing/ord_chaos.rs @@ -2,6 +2,8 @@ use std::cell::Cell; use std::cmp::Ordering::{self, *}; use std::ptr; +use crate::string::String; + // Minimal type with an `Ord` implementation violating transitivity. #[derive(Debug)] pub(crate) enum Cyclic3 { @@ -79,3 +81,31 @@ impl PartialEq for Governed<'_, T> { } impl Eq for Governed<'_, T> {} + +// Comparison based only on the ID, the name is ignored. +#[derive(Debug)] +pub(crate) struct IdBased { + pub id: u32, + #[allow(dead_code)] + pub name: String, +} + +impl PartialEq for IdBased { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for IdBased {} + +impl PartialOrd for IdBased { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for IdBased { + fn cmp(&self, other: &Self) -> Ordering { + self.id.cmp(&other.id) + } +}