#![allow(missing_docs)]
use intid_derive::IntegerId;
use itertools::Itertools;
use serde_derive::{Deserialize, Serialize};
#[cfg(feature = "serde")]
use serde_test::{assert_tokens, Token};
use idmap::{direct_idmap, DirectIdMap};
use KnownState::*;
#[test]
fn remove() {
let mut m = important_cities();
assert_eq!(m.remove(NewMexico), None);
for state in IMPORTANT_STATES {
assert_eq!(Some(state.city()), m.remove(state), "{m:#?}");
}
assert_eq!(m.len(), 0);
assert_eq!(m.remove(NewMexico), None);
assert_eq!(m.remove(NorthDakota), None);
}
#[test]
fn eq() {
let first = important_cities();
let second = important_cities()
.into_iter()
.rev()
.collect::<DirectIdMap<_, _>>();
assert_eq!(first, second);
}
#[test]
fn from_iter() {
let xs = [
(California, "San Diego"),
(NewYork, "New York"),
(Arizona, "Phoenix"),
];
let map: DirectIdMap<_, _> = xs.iter().copied().collect();
for &(k, v) in &xs {
assert_eq!(map.get(k), Some(&v));
}
check_missing(TINY_STATES, &map);
}
#[test]
fn clone() {
let original = important_cities();
let cloned = original.clone();
assert_eq!(original, cloned);
}
#[test]
fn index() {
let map = important_cities();
for state in IMPORTANT_STATES {
assert_eq!(map[state], state.city());
}
}
#[test]
fn declaration_order() {
let map = important_cities();
let actual_entries = map
.iter()
.map(|(state, &city)| (state, city))
.collect::<Vec<_>>();
let declared_entries = actual_entries.iter().copied().sorted().collect_vec();
assert_eq!(actual_entries, declared_entries);
let reversed_map = actual_entries
.iter()
.rev()
.copied()
.collect::<DirectIdMap<KnownState, &'static str>>();
let reversed_entries = reversed_map
.iter()
.map(|(state, &city)| (state, city))
.collect::<Vec<_>>();
assert_eq!(reversed_entries, declared_entries);
}
#[test]
#[should_panic = "index out of bounds"]
#[allow(clippy::no_effect)] fn index_nonexistent() {
let map = important_cities();
map[NorthDakota];
}
#[test]
#[cfg(any())] fn entry_insert() {
let mut map = important_cities();
for &state in ALL_STATES {
let value = *map.entry(state).or_insert_with(|| state.city());
assert_eq!(value, state.city());
}
check_cities(ALL_STATES, &map);
}
#[test]
fn extend_ref() {
let important = important_cities();
let mut all = DirectIdMap::new();
all.insert(NewMexico, "Albuquerque");
all.insert(California, "San Diego");
all.insert(NorthDakota, "Fargo");
all.extend(&important);
assert_eq!(all.len(), 5);
assert_eq!(all.iter().nth(1).unwrap(), (California, &California.city()));
assert_eq!(all.iter().nth(4).unwrap(), (NorthDakota, &"Fargo"));
check_cities(ALL_STATES, &all);
}
#[test]
fn retain() {
let mut map = important_cities();
map.retain(|state, _| match state {
NewYork => false, California | Arizona => true,
_ => unreachable!(),
});
assert_eq!(map.len(), 2);
check_cities(&[Arizona, California], &map);
check_missing(TINY_STATES, &map);
}
fn important_cities() -> DirectIdMap<KnownState, &'static str> {
direct_idmap! {
Arizona => "Phoenix",
NewYork => "New York City",
California => "Los Angeles"
}
}
#[derive(IntegerId, Debug, Copy, Clone, PartialEq, Serialize, Deserialize, Ord, PartialOrd, Eq)]
enum KnownState {
Arizona,
California,
NewMexico,
NewYork,
NorthDakota,
}
fn check_missing(states: &[KnownState], target: &DirectIdMap<KnownState, &'static str>) {
for state in states {
state.check_missing(target);
}
}
fn check_cities(states: &[KnownState], target: &DirectIdMap<KnownState, &'static str>) {
for state in states {
state.check_city(target);
}
}
static ALL_STATES: &[KnownState] = &[Arizona, California, NewMexico, NewYork, NorthDakota];
static IMPORTANT_STATES: &[KnownState] = &[Arizona, NewYork, California];
static TINY_STATES: &[KnownState] = &[NorthDakota, NewMexico];
impl KnownState {
fn city(self) -> &'static str {
match self {
Arizona => "Phoenix",
California => "Los Angeles",
NewMexico => "Albuquerque",
NewYork => "New York City",
NorthDakota => "Fargo",
}
}
fn check_missing(self, target: &DirectIdMap<KnownState, &'static str>) {
assert_eq!(target.get(self), None, "Expected no city for {self:?}");
}
fn check_city(self, target: &DirectIdMap<KnownState, &'static str>) {
assert_eq!(
target.get(self),
Some(&self.city()),
"Unexpected city for {self:?}"
);
}
}
#[test]
fn wrapper() {
let data = direct_idmap! {
ExampleWrapper(32) => "abc",
ExampleWrapper(42) => "life",
};
assert_eq!(data[ExampleWrapper(32)], "abc");
assert_eq!(data[ExampleWrapper(42)], "life");
assert_eq!(data.get(ExampleWrapper(76)), None);
}
#[test]
fn struct_wrapper() {
let data = direct_idmap! {
ExampleStructWrapper::new(32) => "abc",
ExampleStructWrapper::new(42) => "life"
};
assert_eq!(data[ExampleStructWrapper::new(32)], "abc");
assert_eq!(data[ExampleStructWrapper::new(42)], "life");
assert_eq!(data.get(ExampleStructWrapper::new(76)), None);
}
#[derive(IntegerId, Copy, Clone, Debug, Eq, PartialEq)]
struct ExampleWrapper(u16);
#[derive(IntegerId, Copy, Clone, Debug, Eq, PartialEq)]
struct ExampleStructWrapper {
value: u16,
}
impl ExampleStructWrapper {
#[inline]
fn new(value: u16) -> Self {
ExampleStructWrapper { value }
}
}
#[test]
#[cfg(feature = "serde")]
fn serde() {
macro_rules! state_tokens {
($len:expr, $($state:expr => $city:expr),*) => (&[
Token::Map { len: Some($len) },
$(
Token::Enum { name: "KnownState" },
Token::Str(stringify!($state)),
Token::Unit,
Token::BorrowedStr($city),
)*
Token::MapEnd
]);
}
const EXPECTED_TOKENS: &[Token] = state_tokens!(3,
Arizona => "Phoenix",
California => "Los Angeles",
NewYork => "New York City"
);
assert_tokens(&important_cities(), EXPECTED_TOKENS);
}