use crate::default::OrdStoredKey;
use alloc::fmt::Debug;
use std::cmp::Ordering;
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
#[derive(Debug)]
pub struct CrashTestDummy {
pub id: usize,
cloned: AtomicUsize,
dropped: AtomicUsize,
queried: AtomicUsize,
}
impl CrashTestDummy {
pub fn new(id: usize) -> CrashTestDummy {
CrashTestDummy {
id,
cloned: AtomicUsize::new(0),
dropped: AtomicUsize::new(0),
queried: AtomicUsize::new(0),
}
}
pub fn spawn(&self, panic: Panic) -> Instance<'_> {
Instance { origin: self, panic }
}
pub fn cloned(&self) -> usize {
self.cloned.load(SeqCst)
}
pub fn dropped(&self) -> usize {
self.dropped.load(SeqCst)
}
pub fn queried(&self) -> usize {
self.queried.load(SeqCst)
}
}
#[derive(Debug)]
pub struct Instance<'a> {
origin: &'a CrashTestDummy,
panic: Panic,
}
impl OrdStoredKey for Instance<'_> {
type OrdKeyType = Self;
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Panic {
Never,
InClone,
InDrop,
InQuery,
}
impl Instance<'_> {
pub fn id(&self) -> usize {
self.origin.id
}
pub fn query<R>(&self, result: R) -> R {
self.origin.queried.fetch_add(1, SeqCst);
if self.panic == Panic::InQuery {
panic!("panic in `query`");
}
result
}
}
impl Clone for Instance<'_> {
fn clone(&self) -> Self {
self.origin.cloned.fetch_add(1, SeqCst);
if self.panic == Panic::InClone {
panic!("panic in `clone`");
}
Self { origin: self.origin, panic: Panic::Never }
}
}
impl Drop for Instance<'_> {
fn drop(&mut self) {
self.origin.dropped.fetch_add(1, SeqCst);
if self.panic == Panic::InDrop {
panic!("panic in `drop`");
}
}
}
impl PartialOrd for Instance<'_> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.id().partial_cmp(&other.id())
}
}
impl Ord for Instance<'_> {
fn cmp(&self, other: &Self) -> Ordering {
self.id().cmp(&other.id())
}
}
impl PartialEq for Instance<'_> {
fn eq(&self, other: &Self) -> bool {
self.id().eq(&other.id())
}
}
impl Eq for Instance<'_> {}