objc2/rc/
retained_forwarding_impls.rs

1//! Trivial forwarding impls on `Retained`-like types.
2//!
3//! Kept here to keep `retained.rs` free from this boilerplate, and to allow
4//! re-use in `objc2-core-foundation` and `dispatch2` (this file is symlinked
5//! there as well).
6
7#![forbid(unsafe_code)]
8
9use core::borrow::Borrow;
10use core::cmp::Ordering;
11use core::fmt;
12use core::future::Future;
13use core::hash;
14use core::pin::Pin;
15use core::task::{Context, Poll};
16#[cfg(feature = "std")] // TODO: Use core::error::Error once 1.81 is in MSRV
17use std::error::Error;
18#[cfg(feature = "std")]
19use std::io;
20
21use super::Retained;
22
23impl<T: ?Sized + PartialEq<U>, U: ?Sized> PartialEq<Retained<U>> for Retained<T> {
24    #[inline]
25    fn eq(&self, other: &Retained<U>) -> bool {
26        (**self).eq(&**other)
27    }
28
29    #[inline]
30    #[allow(clippy::partialeq_ne_impl)]
31    fn ne(&self, other: &Retained<U>) -> bool {
32        (**self).ne(&**other)
33    }
34}
35
36impl<T: Eq + ?Sized> Eq for Retained<T> {}
37
38impl<T: ?Sized + PartialOrd<U>, U: ?Sized> PartialOrd<Retained<U>> for Retained<T> {
39    #[inline]
40    fn partial_cmp(&self, other: &Retained<U>) -> Option<Ordering> {
41        (**self).partial_cmp(&**other)
42    }
43    #[inline]
44    fn lt(&self, other: &Retained<U>) -> bool {
45        (**self).lt(&**other)
46    }
47    #[inline]
48    fn le(&self, other: &Retained<U>) -> bool {
49        (**self).le(&**other)
50    }
51    #[inline]
52    fn ge(&self, other: &Retained<U>) -> bool {
53        (**self).ge(&**other)
54    }
55    #[inline]
56    fn gt(&self, other: &Retained<U>) -> bool {
57        (**self).gt(&**other)
58    }
59}
60
61impl<T: Ord + ?Sized> Ord for Retained<T> {
62    #[inline]
63    fn cmp(&self, other: &Self) -> Ordering {
64        (**self).cmp(&**other)
65    }
66}
67
68impl<T: hash::Hash + ?Sized> hash::Hash for Retained<T> {
69    fn hash<H: hash::Hasher>(&self, state: &mut H) {
70        (**self).hash(state);
71    }
72}
73
74impl<T: ?Sized> hash::Hasher for Retained<T>
75where
76    for<'a> &'a T: hash::Hasher,
77{
78    fn finish(&self) -> u64 {
79        (&**self).finish()
80    }
81    fn write(&mut self, bytes: &[u8]) {
82        (&**self).write(bytes);
83    }
84    fn write_u8(&mut self, i: u8) {
85        (&**self).write_u8(i);
86    }
87    fn write_u16(&mut self, i: u16) {
88        (&**self).write_u16(i);
89    }
90    fn write_u32(&mut self, i: u32) {
91        (&**self).write_u32(i);
92    }
93    fn write_u64(&mut self, i: u64) {
94        (&**self).write_u64(i);
95    }
96    fn write_u128(&mut self, i: u128) {
97        (&**self).write_u128(i);
98    }
99    fn write_usize(&mut self, i: usize) {
100        (&**self).write_usize(i);
101    }
102    fn write_i8(&mut self, i: i8) {
103        (&**self).write_i8(i);
104    }
105    fn write_i16(&mut self, i: i16) {
106        (&**self).write_i16(i);
107    }
108    fn write_i32(&mut self, i: i32) {
109        (&**self).write_i32(i);
110    }
111    fn write_i64(&mut self, i: i64) {
112        (&**self).write_i64(i);
113    }
114    fn write_i128(&mut self, i: i128) {
115        (&**self).write_i128(i);
116    }
117    fn write_isize(&mut self, i: isize) {
118        (&**self).write_isize(i);
119    }
120}
121
122impl<'a, T: ?Sized> hash::Hasher for &'a Retained<T>
123where
124    &'a T: hash::Hasher,
125{
126    fn finish(&self) -> u64 {
127        (&***self).finish()
128    }
129    fn write(&mut self, bytes: &[u8]) {
130        (&***self).write(bytes);
131    }
132    fn write_u8(&mut self, i: u8) {
133        (&***self).write_u8(i);
134    }
135    fn write_u16(&mut self, i: u16) {
136        (&***self).write_u16(i);
137    }
138    fn write_u32(&mut self, i: u32) {
139        (&***self).write_u32(i);
140    }
141    fn write_u64(&mut self, i: u64) {
142        (&***self).write_u64(i);
143    }
144    fn write_u128(&mut self, i: u128) {
145        (&***self).write_u128(i);
146    }
147    fn write_usize(&mut self, i: usize) {
148        (&***self).write_usize(i);
149    }
150    fn write_i8(&mut self, i: i8) {
151        (&***self).write_i8(i);
152    }
153    fn write_i16(&mut self, i: i16) {
154        (&***self).write_i16(i);
155    }
156    fn write_i32(&mut self, i: i32) {
157        (&***self).write_i32(i);
158    }
159    fn write_i64(&mut self, i: i64) {
160        (&***self).write_i64(i);
161    }
162    fn write_i128(&mut self, i: i128) {
163        (&***self).write_i128(i);
164    }
165    fn write_isize(&mut self, i: isize) {
166        (&***self).write_isize(i);
167    }
168}
169
170macro_rules! forward_fmt_impl {
171    ($trait:path) => {
172        impl<T: $trait + ?Sized> $trait for Retained<T> {
173            #[inline]
174            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175                (**self).fmt(f)
176            }
177        }
178    };
179}
180
181forward_fmt_impl!(fmt::Binary);
182forward_fmt_impl!(fmt::Debug);
183forward_fmt_impl!(fmt::Display);
184forward_fmt_impl!(fmt::LowerExp);
185forward_fmt_impl!(fmt::LowerHex);
186forward_fmt_impl!(fmt::Octal);
187// forward_fmt_impl!(fmt::Pointer);
188forward_fmt_impl!(fmt::UpperExp);
189forward_fmt_impl!(fmt::UpperHex);
190
191impl<'a, T: ?Sized> fmt::Write for &'a Retained<T>
192where
193    &'a T: fmt::Write,
194{
195    #[inline]
196    fn write_str(&mut self, s: &str) -> fmt::Result {
197        (&***self).write_str(s)
198    }
199
200    #[inline]
201    fn write_char(&mut self, c: char) -> fmt::Result {
202        (&***self).write_char(c)
203    }
204
205    #[inline]
206    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
207        (&***self).write_fmt(args)
208    }
209}
210
211impl<T: ?Sized> Borrow<T> for Retained<T> {
212    fn borrow(&self) -> &T {
213        // Auto-derefs
214        self
215    }
216}
217
218// Forward to inner type's `AsRef`.
219//
220// This is different from what `Box` does, but is desirable in our case, as it
221// allows going directly to superclasses.
222//
223// See also discussion in:
224// <https://internals.rust-lang.org/t/semantics-of-asref/17016>
225impl<T: ?Sized + AsRef<U>, U: ?Sized> AsRef<U> for Retained<T> {
226    fn as_ref(&self) -> &U {
227        (**self).as_ref()
228    }
229}
230
231#[cfg(feature = "std")]
232impl<T: ?Sized + Error> Error for Retained<T> {
233    fn source(&self) -> Option<&(dyn Error + 'static)> {
234        (**self).source()
235    }
236}
237
238#[cfg(feature = "std")]
239impl<T: ?Sized> io::Read for Retained<T>
240where
241    for<'a> &'a T: io::Read,
242{
243    #[inline]
244    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
245        (&**self).read(buf)
246    }
247
248    #[inline]
249    fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
250        (&**self).read_vectored(bufs)
251    }
252
253    #[inline]
254    fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
255        (&**self).read_to_end(buf)
256    }
257
258    #[inline]
259    fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
260        (&**self).read_to_string(buf)
261    }
262
263    #[inline]
264    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
265        (&**self).read_exact(buf)
266    }
267}
268
269#[cfg(feature = "std")]
270impl<'a, T: ?Sized> io::Read for &'a Retained<T>
271where
272    &'a T: io::Read,
273{
274    #[inline]
275    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
276        (&***self).read(buf)
277    }
278
279    #[inline]
280    fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
281        (&***self).read_vectored(bufs)
282    }
283
284    #[inline]
285    fn read_to_end(&mut self, buf: &mut std::vec::Vec<u8>) -> io::Result<usize> {
286        (&***self).read_to_end(buf)
287    }
288
289    #[inline]
290    fn read_to_string(&mut self, buf: &mut std::string::String) -> io::Result<usize> {
291        (&***self).read_to_string(buf)
292    }
293
294    #[inline]
295    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
296        (&***self).read_exact(buf)
297    }
298}
299
300#[cfg(feature = "std")]
301impl<T: ?Sized> io::Write for Retained<T>
302where
303    for<'a> &'a T: io::Write,
304{
305    #[inline]
306    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
307        (&**self).write(buf)
308    }
309
310    #[inline]
311    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
312        (&**self).write_vectored(bufs)
313    }
314
315    #[inline]
316    fn flush(&mut self) -> io::Result<()> {
317        (&**self).flush()
318    }
319
320    #[inline]
321    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
322        (&**self).write_all(buf)
323    }
324
325    #[inline]
326    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
327        (&**self).write_fmt(fmt)
328    }
329}
330
331#[cfg(feature = "std")]
332impl<'a, T: ?Sized> io::Write for &'a Retained<T>
333where
334    &'a T: io::Write,
335{
336    #[inline]
337    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
338        (&***self).write(buf)
339    }
340
341    #[inline]
342    fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
343        (&***self).write_vectored(bufs)
344    }
345
346    #[inline]
347    fn flush(&mut self) -> io::Result<()> {
348        (&***self).flush()
349    }
350
351    #[inline]
352    fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
353        (&***self).write_all(buf)
354    }
355
356    #[inline]
357    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> {
358        (&***self).write_fmt(fmt)
359    }
360}
361
362#[cfg(feature = "std")]
363impl<T: ?Sized> io::Seek for Retained<T>
364where
365    for<'a> &'a T: io::Seek,
366{
367    #[inline]
368    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
369        (&**self).seek(pos)
370    }
371
372    #[inline]
373    fn stream_position(&mut self) -> io::Result<u64> {
374        (&**self).stream_position()
375    }
376}
377
378#[cfg(feature = "std")]
379impl<'a, T: ?Sized> io::Seek for &'a Retained<T>
380where
381    &'a T: io::Seek,
382{
383    #[inline]
384    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
385        (&***self).seek(pos)
386    }
387
388    #[inline]
389    fn stream_position(&mut self) -> io::Result<u64> {
390        (&***self).stream_position()
391    }
392}
393
394impl<'a, T: ?Sized> Future for &'a Retained<T>
395where
396    &'a T: Future,
397{
398    type Output = <&'a T as Future>::Output;
399
400    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
401        <&T>::poll(Pin::new(&mut &***self), cx)
402    }
403}
404
405impl<A, T: ?Sized> Extend<A> for Retained<T>
406where
407    for<'a> &'a T: Extend<A>,
408{
409    #[inline]
410    fn extend<I: IntoIterator<Item = A>>(&mut self, iter: I) {
411        (&**self).extend(iter)
412    }
413}
414
415impl<'a, A, T: ?Sized> Extend<A> for &'a Retained<T>
416where
417    &'a T: Extend<A>,
418{
419    #[inline]
420    fn extend<I: IntoIterator<Item = A>>(&mut self, iter: I) {
421        (&***self).extend(iter)
422    }
423}
424
425// TODO: impl Fn traits, CoerceUnsized, Stream and so on when stabilized