1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
//! Implement a Fallible Arc
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
use super::FallibleBox;
use super::TryClone;
use crate::TryReserveError;
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
use alloc::boxed::Box;
use alloc::sync::Arc;
/// trait to implement Fallible Arc
#[cfg_attr(
any(not(feature = "unstable"), feature = "rust_1_57"),
deprecated(
since = "0.3.1",
note = "⚠️️️this function is not completely fallible, it can panic !, see [issue](https://github.com/vcombey/fallible_collections/issues/13). help wanted"
)
)]
pub trait FallibleArc<T> {
/// try creating a new Arc, returning a Result<Box<T>,
/// TryReserveError> if allocation failed
fn try_new(t: T) -> Result<Self, TryReserveError>
where
Self: Sized;
}
#[allow(deprecated)]
impl<T> FallibleArc<T> for Arc<T> {
fn try_new(t: T) -> Result<Self, TryReserveError> {
#[cfg(any(not(feature = "unstable"), feature = "rust_1_57"))]
{
// doesn't work as the inner variable of arc are also stocked in the box
let b = <Box<T> as FallibleBox<T>>::try_new(t)?;
Ok(Arc::from(b))
}
#[cfg(all(feature = "unstable", not(feature = "rust_1_57")))]
{
use alloc::alloc::Layout;
use alloc::collections::TryReserveErrorKind;
Arc::try_new(t).map_err(|_e| {
TryReserveErrorKind::AllocError {
layout: Layout::new::<Arc<T>>(), // This is bullshit
non_exhaustive: (),
}
.into()
})
}
}
}
/// Just a TryClone boilerplate for Arc
impl<T: ?Sized> TryClone for Arc<T> {
fn try_clone(&self) -> Result<Self, TryReserveError> {
Ok(self.clone())
}
}
#[cfg(test)]
mod test {
#[test]
fn fallible_rc() {
use std::sync::Arc;
let mut x = Arc::new(3);
*Arc::get_mut(&mut x).unwrap() = 4;
assert_eq!(*x, 4);
let _y = Arc::clone(&x);
assert!(Arc::get_mut(&mut x).is_none());
}
}
|