exhaust/impls/
std_impls.rs

1#![allow(clippy::wildcard_imports)]
2
3use core::pin::Pin;
4use core::{fmt, iter};
5
6use crate::iteration::{peekable_exhaust, FlatZipMap};
7use crate::patterns::{
8    delegate_factory_and_iter, factory_is_self, impl_newtype_generic, impl_singleton,
9    impl_via_array,
10};
11use crate::Exhaust;
12
13use super::alloc_impls::{ExhaustMap, ExhaustSet, MapFactory};
14
15mod collections {
16    use super::*;
17    use alloc::vec::Vec;
18    use core::hash::{BuildHasher, Hash};
19    use std::collections::{HashMap, HashSet};
20
21    // Note: This impl is essentially identical to the one for `BTreeSet`.
22    impl<T, S> Exhaust for HashSet<T, S>
23    where
24        T: Exhaust + Eq + Hash,
25        S: Default + BuildHasher,
26    {
27        type Iter = ExhaustSet<T>;
28        type Factory = Vec<T::Factory>;
29        fn exhaust_factories() -> Self::Iter {
30            ExhaustSet::default()
31        }
32
33        fn from_factory(factory: Self::Factory) -> Self {
34            factory.into_iter().map(T::from_factory).collect()
35        }
36    }
37
38    impl<K, V, S> Exhaust for HashMap<K, V, S>
39    where
40        K: Exhaust + Eq + Hash,
41        V: Exhaust,
42        S: Default + BuildHasher,
43    {
44        type Iter = ExhaustMap<<HashSet<K, S> as Exhaust>::Iter, V>;
45
46        fn exhaust_factories() -> Self::Iter {
47            ExhaustMap::new(peekable_exhaust::<HashSet<K, S>>())
48        }
49
50        type Factory = MapFactory<K, V>;
51
52        fn from_factory(factory: Self::Factory) -> Self {
53            factory
54                .into_iter()
55                .map(|(k, v)| (K::from_factory(k), V::from_factory(v)))
56                .collect()
57        }
58    }
59}
60
61mod io {
62    use super::*;
63    use crate::patterns::delegate_factory_and_iter;
64    use std::io;
65
66    /// Produces each combination of a buffer state and a cursor position, except for those
67    /// where the position is beyond the end of the buffer.
68    impl<T: Exhaust + AsRef<[u8]> + Clone + fmt::Debug> Exhaust for io::Cursor<T> {
69        type Iter = FlatZipMap<crate::Iter<T>, core::ops::RangeInclusive<u64>, io::Cursor<T>>;
70        fn exhaust_factories() -> Self::Iter {
71            FlatZipMap::new(
72                T::exhaust(),
73                |buf| 0..=(buf.as_ref().len() as u64),
74                |buf, pos| {
75                    let mut cursor = io::Cursor::new(buf);
76                    cursor.set_position(pos);
77                    cursor
78                },
79            )
80        }
81        factory_is_self!();
82    }
83
84    impl<T: io::Read + Exhaust> Exhaust for io::BufReader<T> {
85        delegate_factory_and_iter!(T);
86        fn from_factory(factory: Self::Factory) -> Self {
87            io::BufReader::new(T::from_factory(factory))
88        }
89    }
90
91    impl<T: io::Write + Exhaust> Exhaust for io::BufWriter<T> {
92        delegate_factory_and_iter!(T);
93        fn from_factory(factory: Self::Factory) -> Self {
94            io::BufWriter::new(T::from_factory(factory))
95        }
96    }
97
98    impl<T: io::Read + Exhaust, U: io::Read + Exhaust> Exhaust for io::Chain<T, U> {
99        delegate_factory_and_iter!((T, U));
100
101        fn from_factory(factory: Self::Factory) -> Self {
102            let (first, second) = <(T, U)>::from_factory(factory);
103            first.chain(second)
104        }
105    }
106
107    impl Exhaust for io::Empty {
108        type Iter = iter::Once<io::Empty>;
109        fn exhaust_factories() -> Self::Iter {
110            iter::once(io::empty())
111        }
112        factory_is_self!();
113    }
114
115    impl<T: io::Write + Exhaust> Exhaust for io::LineWriter<T> {
116        delegate_factory_and_iter!(T);
117        fn from_factory(factory: Self::Factory) -> Self {
118            io::LineWriter::new(T::from_factory(factory))
119        }
120    }
121
122    impl Exhaust for io::Repeat {
123        delegate_factory_and_iter!(u8);
124        fn from_factory(factory: Self::Factory) -> Self {
125            io::repeat(factory)
126        }
127    }
128
129    impl_singleton!([], io::Sink);
130    impl_singleton!([], io::Stderr, io::stderr());
131    impl_singleton!([], io::Stdin, io::stdin());
132    impl_singleton!([], io::Stdout, io::stdout());
133
134    // no impl for io::Take because it takes a 64-bit parameter
135    // no impl for io::Error[Kind] because it is #[non_exhaustive]
136    // no impl for io::SeekFrom because it takes a 64-bit parameter
137}
138
139mod sync {
140    use super::*;
141    use std::sync;
142
143    impl_newtype_generic!(T: [], sync::Arc<T>, sync::Arc::new);
144    impl_newtype_generic!(T: [], Pin<sync::Arc<T>>, sync::Arc::pin);
145
146    impl_newtype_generic!(T: [], sync::Mutex<T>, sync::Mutex::new);
147    impl_newtype_generic!(T: [], sync::RwLock<T>, sync::RwLock::new);
148
149    impl<T: Exhaust> Exhaust for sync::OnceLock<T> {
150        delegate_factory_and_iter!(Option<T>);
151
152        fn from_factory(factory: Self::Factory) -> Self {
153            let cell = sync::OnceLock::new();
154            if let Some(value) = Option::<T>::from_factory(factory) {
155                match cell.set(value) {
156                    Ok(()) => {}
157                    Err(_) => unreachable!(),
158                }
159            }
160            cell
161        }
162    }
163
164    impl_via_array!(
165        sync::mpsc::RecvTimeoutError,
166        [Self::Timeout, Self::Disconnected]
167    );
168    impl_via_array!(sync::mpsc::TryRecvError, [Self::Empty, Self::Disconnected]);
169    impl_singleton!([], sync::mpsc::RecvError, sync::mpsc::RecvError);
170    impl<T: Exhaust> Exhaust for sync::mpsc::TrySendError<T> {
171        delegate_factory_and_iter!(remote::TrySendError<T>);
172        fn from_factory(factory: Self::Factory) -> Self {
173            match remote::TrySendError::from_factory(factory) {
174                remote::TrySendError::Full(t) => Self::Full(t),
175                remote::TrySendError::Disconnected(t) => Self::Disconnected(t),
176            }
177        }
178    }
179    impl_newtype_generic!(T: [], sync::mpsc::SendError<T>, sync::mpsc::SendError);
180
181    // TODO: Add `OnceLock` when we bump MSRV.
182    //
183    // * sync::Condvar is stateful in a way we cannot handle.
184    // * sync::Once could be implemented, but is dubious.
185    // * sync::TryLockError could be implemented, but it doesn’t make sense to do so, since the
186    //   thing it is expected to contain is a lock guard, which we cannot construct.
187
188    mod remote {
189        #![allow(missing_debug_implementations)]
190
191        #[derive(crate::Exhaust)]
192        pub enum TrySendError<T> {
193            Full(T),
194            Disconnected(T),
195        }
196    }
197}