#[cfg(feature = "std")]
mod arc_error {
use std::error::Error;
use std::fmt;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct ArcError(pub Arc<crate::Error>);
impl ArcError {
pub fn new(error: crate::Error) -> Self {
ArcError(Arc::new(error))
}
}
impl fmt::Display for ArcError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
}
}
impl Error for ArcError {}
}
#[cfg(feature = "std")]
pub use arc_error::ArcError;
use crate::{
DynFallibleTryDropStrategy, FallibleTryDropStrategy, PureTryDrop, RepeatableTryDrop,
TryDropStrategy,
};
#[allow(unused_imports)] use crate::TryDrop;
use core::marker::PhantomData;
#[cfg_attr(
feature = "derives",
derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
)]
#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
pub struct InfallibleToFallibleTryDropStrategyAdapter<T: TryDropStrategy, E: Into<anyhow::Error>> {
#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(main_field))]
pub inner: T,
_error: PhantomData<E>,
}
impl<T: TryDropStrategy, E: Into<anyhow::Error>> InfallibleToFallibleTryDropStrategyAdapter<T, E> {
pub fn new(value: T) -> Self {
Self {
inner: value,
_error: PhantomData,
}
}
#[cfg(feature = "shrinkwraprs")]
pub fn take(this: Self) -> T {
this.inner
}
}
impl<T: TryDropStrategy, E: Into<anyhow::Error>> FallibleTryDropStrategy
for InfallibleToFallibleTryDropStrategyAdapter<T, E>
{
type Error = E;
fn try_handle_error(&self, error: anyhow::Error) -> Result<(), Self::Error> {
self.inner.handle_error(error);
Ok(())
}
}
#[cfg_attr(
feature = "derives",
derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
)]
#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
pub struct RepeatableTryDropAdapter<T: PureTryDrop> {
#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(main_field))]
pub inner: T,
dropped: bool,
panic_on_double_drop: bool,
}
impl<T: PureTryDrop + Default> Default for RepeatableTryDropAdapter<T> {
fn default() -> Self {
Self::new(T::default())
}
}
impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
pub fn new(item: T) -> Self {
Self {
inner: item,
dropped: false,
panic_on_double_drop: true,
}
}
}
#[cfg(not(feature = "shrinkwraprs"))]
impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
pub fn with_panic_on_double_drop(mut self, panic_on_double_drop: bool) -> Self {
self.panic_on_double_drop = panic_on_double_drop;
self
}
pub fn dropped(&self) -> bool {
self.dropped
}
pub fn panic_on_double_drop(&self) -> bool {
self.panic_on_double_drop
}
}
#[cfg(feature = "shrinkwraprs")]
impl<T: PureTryDrop> RepeatableTryDropAdapter<T> {
pub fn with_panic_on_double_drop(mut this: Self, panic_on_double_drop: bool) -> Self {
this.panic_on_double_drop = panic_on_double_drop;
this
}
pub fn dropped(this: &Self) -> bool {
this.dropped
}
pub fn panic_on_double_drop(this: &Self) -> bool {
this.panic_on_double_drop
}
pub fn take(this: Self) -> T {
this.inner
}
}
impl<T: PureTryDrop> PureTryDrop for RepeatableTryDropAdapter<T> {
type Error = T::Error;
type FallbackTryDropStrategy = T::FallbackTryDropStrategy;
type TryDropStrategy = T::TryDropStrategy;
fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy {
self.inner.fallback_try_drop_strategy()
}
fn try_drop_strategy(&self) -> &Self::TryDropStrategy {
self.inner.try_drop_strategy()
}
unsafe fn try_drop(&mut self) -> Result<(), Self::Error> {
if self.dropped && self.panic_on_double_drop {
panic!("tried to drop object twice, this is an invalid operation")
} else {
self.inner.try_drop()?;
self.dropped = true;
Ok(())
}
}
}
unsafe impl<T: PureTryDrop> RepeatableTryDrop for RepeatableTryDropAdapter<T> {}
#[cfg_attr(
feature = "derives",
derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
)]
#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
#[cfg_attr(feature = "shrinkwraprs", shrinkwrap(mutable))]
pub struct DropAdapter<TD: PureTryDrop>(pub TD);
impl<TD: PureTryDrop> Drop for DropAdapter<TD> {
fn drop(&mut self) {
let result = unsafe { self.0.try_drop() };
if let Err(error) = result {
let handler = FallbackTryDropStrategyHandler::new(
TryDropStrategyRef(self.0.fallback_try_drop_strategy()),
FallibleTryDropStrategyRef(self.0.try_drop_strategy()),
);
handler.handle_error(error.into())
}
}
}
impl<RTD: RepeatableTryDrop> PureTryDrop for DropAdapter<RTD> {
type Error = RTD::Error;
type FallbackTryDropStrategy = RTD::FallbackTryDropStrategy;
type TryDropStrategy = RTD::TryDropStrategy;
fn fallback_try_drop_strategy(&self) -> &Self::FallbackTryDropStrategy {
self.0.fallback_try_drop_strategy()
}
fn try_drop_strategy(&self) -> &Self::TryDropStrategy {
self.0.try_drop_strategy()
}
unsafe fn try_drop(&mut self) -> Result<(), Self::Error> {
self.0.try_drop()
}
}
unsafe impl<RTD: RepeatableTryDrop> RepeatableTryDrop for DropAdapter<RTD> {}
impl<TD: PureTryDrop> From<TD> for DropAdapter<TD> {
fn from(t: TD) -> Self {
t.adapt()
}
}
#[cfg_attr(
feature = "derives",
derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
)]
#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
pub struct FallibleTryDropStrategyRef<'a, T: FallibleTryDropStrategy>(pub &'a T);
impl<'a, T: FallibleTryDropStrategy> FallibleTryDropStrategy for FallibleTryDropStrategyRef<'a, T> {
type Error = T::Error;
fn try_handle_error(&self, error: anyhow::Error) -> Result<(), Self::Error> {
self.0.try_handle_error(error)
}
}
#[cfg_attr(
feature = "derives",
derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)
)]
#[cfg_attr(feature = "shrinkwraprs", derive(Shrinkwrap))]
pub struct TryDropStrategyRef<'a, T: TryDropStrategy>(pub &'a T);
impl<'a, T: TryDropStrategy> TryDropStrategy for TryDropStrategyRef<'a, T> {
fn handle_error(&self, error: anyhow::Error) {
self.0.handle_error(error)
}
}
#[cfg_attr(
feature = "derives",
derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default)
)]
pub struct FallbackTryDropStrategyHandler<FDS, FTDS>
where
FDS: TryDropStrategy,
FTDS: FallibleTryDropStrategy,
{
pub fallback_try_drop_strategy: FDS,
pub fallible_try_drop_strategy: FTDS,
}
impl<FDS, FTDS> FallbackTryDropStrategyHandler<FDS, FTDS>
where
FDS: TryDropStrategy,
FTDS: FallibleTryDropStrategy,
{
pub fn new(fallback_try_drop_strategy: FDS, fallible_try_drop_strategy: FTDS) -> Self {
Self {
fallback_try_drop_strategy,
fallible_try_drop_strategy,
}
}
}
impl<FDS, FTDS> TryDropStrategy for FallbackTryDropStrategyHandler<FDS, FTDS>
where
FDS: TryDropStrategy,
FTDS: FallibleTryDropStrategy,
{
fn handle_error(&self, error: anyhow::Error) {
if let Err(error) = self.fallible_try_drop_strategy.dyn_try_handle_error(error) {
self.fallback_try_drop_strategy.handle_error(error)
}
}
}