1 #![allow(clippy::module_name_repetitions)] 2 3 use std::error::Error as StdError; 4 use std::fmt::{self, Display}; 5 use std::sync::atomic::{AtomicBool, Ordering}; 6 use std::sync::Arc; 7 8 #[derive(Debug)] 9 pub struct Flag { 10 atomic: Arc<AtomicBool>, 11 } 12 13 impl Flag { new() -> Self14 pub fn new() -> Self { 15 Flag { 16 atomic: Arc::new(AtomicBool::new(false)), 17 } 18 } 19 get(&self) -> bool20 pub fn get(&self) -> bool { 21 self.atomic.load(Ordering::Relaxed) 22 } 23 } 24 25 #[derive(Debug)] 26 pub struct DetectDrop { 27 has_dropped: Flag, 28 } 29 30 impl DetectDrop { new(has_dropped: &Flag) -> Self31 pub fn new(has_dropped: &Flag) -> Self { 32 DetectDrop { 33 has_dropped: Flag { 34 atomic: Arc::clone(&has_dropped.atomic), 35 }, 36 } 37 } 38 } 39 40 impl StdError for DetectDrop {} 41 42 impl Display for DetectDrop { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 44 write!(f, "oh no!") 45 } 46 } 47 48 impl Drop for DetectDrop { drop(&mut self)49 fn drop(&mut self) { 50 let already_dropped = self.has_dropped.atomic.swap(true, Ordering::Relaxed); 51 assert!(!already_dropped); 52 } 53 } 54