use crate::internal_prelude::*;
#[derive(Debug)]
pub(crate) struct ProtectedWeak<P: ?Sized>(Weak<P>);
#[derive(Debug, Deref, DerefMut)]
pub(crate) struct ProtectedArc<P: ?Sized> {
bomb: DropBomb,
#[deref(forward)]
#[deref_mut(forward)]
arc: Arc<P>,
}
impl<P: ?Sized> ProtectedWeak<P> {
pub(crate) fn new(p: Weak<P>) -> Self {
ProtectedWeak(p)
}
pub(crate) fn upgrade(&self) -> Option<ProtectedArc<P>> {
Some(ProtectedArc::new(self.0.upgrade()?))
}
pub(crate) fn unprotect(self) -> Weak<P> {
self.0
}
}
impl<P: ?Sized> ProtectedArc<P> {
pub(crate) fn new(arc: Arc<P>) -> Self {
let bomb = DropBomb::new_armed();
ProtectedArc { arc, bomb }
}
pub(crate) fn downgrade(&self) -> ProtectedWeak<P> {
ProtectedWeak(Arc::downgrade(&self.arc))
}
pub(crate) fn promise_dropping_is_ok(mut self) -> Arc<P> {
self.bomb.disarm();
self.arc
}
}
#[cfg(test)]
mod test {
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::clone_on_copy)]
#![allow(clippy::dbg_macro)]
#![allow(clippy::mixed_attributes_style)]
#![allow(clippy::print_stderr)]
#![allow(clippy::print_stdout)]
#![allow(clippy::single_char_pattern)]
#![allow(clippy::unwrap_used)]
#![allow(clippy::unchecked_time_subtraction)]
#![allow(clippy::useless_vec)]
#![allow(clippy::needless_pass_by_value)]
#![allow(clippy::string_slice)] #![allow(clippy::let_and_return)]
use super::*;
struct Payload;
#[test]
fn fine() {
let arc = Arc::new(Payload);
let prot = ProtectedArc::new(arc);
let arc = prot.promise_dropping_is_ok();
drop(arc);
}
#[test]
fn bad() {
let arc = Arc::new(Payload);
let mut prot = ProtectedArc::new(arc);
let h = prot.bomb.make_simulated();
drop(prot);
h.expect_exploded();
}
}