1#![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 #[doc = concat!("`", $l, "<T>`")]
34 #[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",);