mappable_rc/
std_impls.rs

1// This module contains lots of trait and function implementations for `Marc` and `Mrc` that are
2// found in the corresponding `std` type. These implementions exclusively make use of other `pub`
3// methods on the types, and all do not use `unsafe`. As such, if the types in general are sound,
4// these impls are too.
5
6#![forbid(unsafe_code)]
7
8use core::borrow::Borrow;
9use core::cmp::Ordering;
10use core::fmt::{self, Debug, Display, Formatter, Pointer};
11use core::hash::{Hash, Hasher};
12use core::ops::Deref;
13
14use alloc::borrow::{Cow, ToOwned};
15use alloc::boxed::Box;
16use alloc::string::String;
17use alloc::vec::Vec;
18
19use crate::Marc;
20use crate::Mrc;
21
22#[cfg(feature = "std")]
23use std::{error::Error, ffi::OsStr, ffi::OsString, path::Path, path::PathBuf};
24
25macro_rules! impls {
26    ($name:ident, $l:literal, $($send:tt)*) => {
27        impl<T: ?Sized> $name<T> {
28            pub fn ptr_eq(this: &Self, other: &Self) -> bool {
29                core::ptr::eq(this.as_ptr(), other.as_ptr())
30            }
31
32            /// Creates a
33            #[doc = concat!("`", $l, "<T>`")]
34            ///  from a value that borrows `T`.
35            ///
36            /// This is just implemented as
37            #[doc = concat!("`", $l, "::map(", $l, "::new(c), |c| c.borrow())`.")]
38            pub fn from_borrow<C>(c: C) -> Self
39            where
40                C: $($send)* Borrow<T> + 'static,
41            {
42                $name::map($name::new(c), |c| c.borrow())
43            }
44        }
45
46        impl<T: ?Sized> AsRef<T> for $name<T> {
47            fn as_ref(&self) -> &T {
48                self.deref()
49            }
50        }
51
52        impl<T: ?Sized> Borrow<T> for $name<T> {
53            fn borrow(&self) -> &T {
54                self.deref()
55            }
56        }
57
58        impl<T: ?Sized + Debug> Debug for $name<T> {
59            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), fmt::Error> {
60                self.deref().fmt(f)
61            }
62        }
63
64        impl<T: $($send)* Default + 'static> Default for $name<T> {
65            fn default() -> Self {
66                $name::new(Default::default())
67            }
68        }
69
70        impl<T: ?Sized + Display> Display for $name<T> {
71            fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), fmt::Error> {
72                self.deref().fmt(f)
73            }
74        }
75
76        impl<T: ?Sized + Eq> Eq for $name<T> {}
77
78        #[cfg(feature = "std")]
79        impl<T: ?Sized + Error> Error for $name<T> {
80            fn source(&self) -> Option<&(dyn Error + 'static)> {
81                self.deref().source()
82            }
83        }
84
85        impl<T: $($send)* Clone + 'static> From<&'_ [T]> for $name<[T]> {
86            fn from(r: &[T]) -> Self {
87                $name::from_borrow(r.to_vec())
88            }
89        }
90
91        impl<T: $($send)* ?Sized + 'static> From<Box<T>> for $name<T> {
92            fn from(b: Box<T>) -> $name<T> {
93                $name::from_borrow(b)
94            }
95        }
96
97        impl<'a, B> From<Cow<'a, B>> for $name<B>
98        where
99            B: ?Sized + ToOwned,
100            &'a B: Into<$name<B>>,
101            <B as ToOwned>::Owned: Into<$name<B>>,
102        {
103            fn from(b: Cow<'a, B>) -> $name<B> {
104                match b {
105                    Cow::Owned(b) => b.into(),
106                    Cow::Borrowed(b) => b.into(),
107                }
108            }
109        }
110
111        #[cfg(feature = "std")]
112        impl From<OsString> for $name<OsStr> {
113            fn from(s: OsString) -> $name<OsStr> {
114                $name::from_borrow(s)
115            }
116        }
117
118        #[cfg(feature = "std")]
119        impl From<PathBuf> for $name<Path> {
120            fn from(p: PathBuf) -> $name<Path> {
121                $name::from_borrow(p)
122            }
123        }
124
125        impl From<String> for $name<str> {
126            fn from(s: String) -> $name<str> {
127                $name::from_borrow(s)
128            }
129        }
130
131        impl<T: $($send)* 'static> From<T> for $name<T> {
132            fn from(t: T) -> $name<T> {
133                $name::new(t)
134            }
135        }
136
137        impl<T: $($send)* 'static> From<Vec<T>> for $name<[T]> {
138            fn from(v: Vec<T>) -> $name<[T]> {
139                $name::from_borrow(v)
140            }
141        }
142
143        impl<T: $($send)* 'static> FromIterator<T> for $name<[T]> {
144            fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> $name<[T]> {
145                iter.into_iter().collect::<Vec<T>>().into()
146            }
147        }
148
149        impl<T: ?Sized + Hash> Hash for $name<T> {
150            fn hash<H: Hasher>(&self, state: &mut H) {
151                self.deref().hash(state)
152            }
153        }
154
155        impl<T: ?Sized + Ord> Ord for $name<T> {
156            fn cmp(&self, other: &Self) -> Ordering {
157                self.deref().cmp(other.deref())
158            }
159        }
160
161        impl<T: ?Sized + PartialEq<T>> PartialEq<$name<T>> for $name<T> {
162            fn eq(&self, other: &Self) -> bool {
163                self.deref().eq(other.deref())
164            }
165        }
166
167        impl<T: ?Sized + PartialOrd<T>> PartialOrd<$name<T>> for $name<T> {
168            fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
169                self.deref().partial_cmp(other.deref())
170            }
171        }
172
173        impl<T: ?Sized> Pointer for $name<T> {
174            fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
175                let t = self.deref();
176                <&T as Pointer>::fmt(&t, f)
177            }
178        }
179
180        impl<T, const N: usize> TryFrom<$name<[T]>> for $name<[T; N]> {
181            type Error = $name<[T]>;
182
183            fn try_from(s: $name<[T]>) -> Result<$name<[T; N]>, $name<[T]>> {
184                $name::try_map(s, |s| s.try_into().ok())
185            }
186        }
187    };
188}
189
190impls!(Marc, "Marc", Send+);
191
192impls!(Mrc, "Mrc",);