Struct drop_tracker::DropItem
source · [−]pub struct DropItem<V> { /* private fields */ }Expand description
An item that will notify the parent DropTracker once it gets dropped.
DropItem instances are created by DropTracker::track, DropTracker::track_with_value,
and related functions. DropItem instances may contain an “underlying value” that affects the
item behavior when used with standard traits. The underlying value is either:
- a clone of
keywhen constructing an item usingtrack(key)(implicit); or valuewhen constructing an item usingtrack_with_value(key, value)(explicit).
To check whether an item is alive or has been dropped, use DropTracker::state or see the
documentation for DropTracker for alternatives.
Coercing and borrowing
DropItem instances may be coerced and borrowed
as the the underlying value type. This means that, for example, if you create a DropItem
using track(String::from("abc")), you may call all of the String methods on that item.
DropItem also implements the standard traits PartialEq,
Eq, PartialOrd, Ord and
Hash, Display, Debug if the
type of the underlying value implements them.
Cloning
DropItem does not implement the Clone trait as it would introduce ambiguity with respect
to understanding whether the item has been dropped or is still alive when using
DropTracker::state.
Double drop
DropItem instances can be dropped twice or more. Doing so will cause a panic, but will not
cause undefined behavior (unless you’re calling drop on an invalid memory location). The panic
on double drop is an useful feature to detect logic errors in destructors.
Safety
Borrowing or performing operations on the underlying value of a DropItem is generally safe
when using safe Rust code. However, DropItems are often used in unsafe code and are used to
detect potential bugs. In those circumstances, it is possible to trigger undefined behavior.
In particular, borrowing or performing operations on a DropItem while another thread is
dropping will result in undefined behavior (although it must be noted that this is a bug in the
caller code and is not something that should happen in safe Rust code).
Only Drop on a DropItem is guaranteed to be safe in all circumstances.
Examples
use drop_tracker::DropTracker;
let mut tracker = DropTracker::<u32>::new();
// Create an item using `123u32` as the key. Implicitly, this also sets its value to `123u32`
let item = tracker.track(123);
// Check that the item is alive
tracker.state(&123).alive().expect("item should be alive");
// Dereference the value of the item
assert_eq!(*item, 123);
assert!(!item.is_power_of_two());
// Drop the item and check that it really got dropped
drop(item);
tracker.state(&123).dropped().expect("item should be dropped");
// Create a new item, this time using an explicit `String` value
let abc_item = tracker.track_with_value(111, String::from("abc"));
// Comparison with other items using `String` work using the underlying `String`
// operations
assert_eq!(abc_item, tracker.track_with_value(222, String::from("abc")));
assert_ne!(abc_item, tracker.track_with_value(333, String::from("def")));
assert!(abc_item < tracker.track_with_value(444, String::from("def")));
// Display, debug and hashing also work using the underlying `String` operations
assert_eq!(format!("{}", abc_item), "abc");
assert_eq!(format!("{:?}", abc_item), "DropItem { value: \"abc\", state: Alive }");
use std::collections::hash_map::DefaultHasher;
use std::hash::Hash;
use std::hash::Hasher;
fn hash<T: Hash + ?Sized>(x: &T) -> u64 {
let mut hasher = DefaultHasher::new();
x.hash(&mut hasher);
hasher.finish()
}
assert_eq!(hash(&abc_item), hash(&"abc"));
// Methods on `String` can be called transparently on items
assert_eq!(abc_item.to_ascii_uppercase(), "ABC");Using hashable items in a set, with an implicit underlying value:
use drop_tracker::DropTracker;
use std::collections::HashSet;
let mut tracker = DropTracker::new();
let mut set = HashSet::from([
tracker.track(1),
tracker.track(2),
tracker.track(3),
]);
set.remove(&3);
tracker.state(&1).alive().expect("first item should be alive");
tracker.state(&2).alive().expect("second item should be alive");
tracker.state(&3).dropped().expect("third item should be dropped");Using hashable items in a set, with an explicit underlying value:
use drop_tracker::DropTracker;
use std::collections::HashSet;
let mut tracker = DropTracker::new();
let mut set = HashSet::from([
tracker.track_with_value(1, String::from("first")),
tracker.track_with_value(2, String::from("second")),
tracker.track_with_value(3, String::from("third")),
]);
set.remove("third");
tracker.state(&1).alive().expect("first item should be alive");
tracker.state(&2).alive().expect("second item should be alive");
tracker.state(&3).dropped().expect("third item should be dropped");Trait Implementations
sourceimpl<V> BorrowMut<V> for DropItem<V>
impl<V> BorrowMut<V> for DropItem<V>
sourcefn borrow_mut(&mut self) -> &mut V
fn borrow_mut(&mut self) -> &mut V
Mutably borrows from an owned value. Read more
sourceimpl<V: BorrowMut<str>> BorrowMut<str> for DropItem<V>
impl<V: BorrowMut<str>> BorrowMut<str> for DropItem<V>
sourcefn borrow_mut(&mut self) -> &mut str
fn borrow_mut(&mut self) -> &mut str
Mutably borrows from an owned value. Read more
sourceimpl<V: PartialOrd<W>, W> PartialOrd<DropItem<W>> for DropItem<V>
impl<V: PartialOrd<W>, W> PartialOrd<DropItem<W>> for DropItem<V>
sourcefn partial_cmp(&self, other: &DropItem<W>) -> Option<Ordering>
fn partial_cmp(&self, other: &DropItem<W>) -> Option<Ordering>
This method returns an ordering between self and other values if one exists. Read more
1.0.0 · sourcefn lt(&self, other: &Rhs) -> bool
fn lt(&self, other: &Rhs) -> bool
This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · sourcefn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for self and other) and is used by the <=
operator. Read more
impl<V: Eq> Eq for DropItem<V>
Auto Trait Implementations
impl<V> RefUnwindSafe for DropItem<V> where
V: RefUnwindSafe,
impl<V> Send for DropItem<V> where
V: Send,
impl<V> Sync for DropItem<V> where
V: Sync,
impl<V> Unpin for DropItem<V> where
V: Unpin,
impl<V> UnwindSafe for DropItem<V> where
V: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more