mod basic;
mod clone;
mod drain;
mod iter;
mod key;
mod overflow;
mod reset;
mod retain;
mod unchecked;
use crate::{Config, KeyPiece};
use core::marker::PhantomData;
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
#[allow(dead_code)]
pub(crate) struct Cfg<Idx, Gen>(PhantomData<(Idx, Gen)>);
impl<Idx: KeyPiece, Gen: KeyPiece> Config for Cfg<Idx, Gen> {
type Idx = Idx;
type Gen = Gen;
}
#[derive(Clone)]
pub(crate) struct DropTracker {
state: Rc<RefCell<TrackerState>>,
}
struct TrackerState {
drops: HashMap<u32, u32>,
next_id: u32,
}
impl DropTracker {
pub(crate) fn new() -> Self {
Self {
state: Rc::new(RefCell::new(TrackerState {
drops: HashMap::new(),
next_id: 0,
})),
}
}
pub(crate) fn make_item(&self) -> DropItem {
let mut state = self.state.borrow_mut();
let id = state.next_id;
state.next_id += 1;
DropItem {
id,
state: self.state.clone(),
}
}
pub(crate) fn total_dropped(&self) -> usize {
self.state.borrow().drops.len()
}
pub(crate) fn total_made(&self) -> u32 {
self.state.borrow().next_id
}
pub(crate) fn assert_all_dropped_exactly_once(&self, n: u32) {
let state = self.state.borrow();
for id in 0..n {
let count = state.drops.get(&id).copied().unwrap_or(0);
assert_eq!(count, 1, "item {id} was dropped {count} times");
}
assert_eq!(state.drops.len(), n as usize);
}
pub(crate) fn assert_none_dropped(&self) {
let dropped = self.total_dropped();
assert_eq!(
dropped, 0,
"expected no drops, but {dropped} items were dropped"
);
}
}
pub(crate) struct DropItem {
id: u32,
state: Rc<RefCell<TrackerState>>,
}
impl Clone for DropItem {
fn clone(&self) -> Self {
let mut state = self.state.borrow_mut();
let id = state.next_id;
state.next_id += 1;
DropItem {
id,
state: self.state.clone(),
}
}
}
impl Drop for DropItem {
fn drop(&mut self) {
let mut state = self.state.borrow_mut();
let count = state.drops.entry(self.id).or_insert(0);
*count += 1;
assert!(*count <= 1, "item {} was dropped {} times", self.id, *count);
}
}