exhaust/impls/
core_ops.rs

1use core::ops;
2
3use crate::patterns::{delegate_factory_and_iter, impl_singleton};
4use crate::Exhaust;
5
6impl<T: Exhaust> Exhaust for ops::Bound<T> {
7    delegate_factory_and_iter!(remote::Bound<T>);
8
9    fn from_factory(factory: Self::Factory) -> Self {
10        match remote::Bound::from_factory(factory) {
11            remote::Bound::Included(v) => ops::Bound::Included(v),
12            remote::Bound::Excluded(v) => ops::Bound::Excluded(v),
13            remote::Bound::Unbounded => ops::Bound::Unbounded,
14        }
15    }
16}
17
18impl<B: Exhaust, C: Exhaust> Exhaust for ops::ControlFlow<B, C> {
19    delegate_factory_and_iter!(remote::ControlFlow<B, C>);
20
21    fn from_factory(factory: Self::Factory) -> Self {
22        match remote::ControlFlow::from_factory(factory) {
23            remote::ControlFlow::Continue(v) => ops::ControlFlow::Continue(v),
24            remote::ControlFlow::Break(v) => ops::ControlFlow::Break(v),
25        }
26    }
27}
28
29// Ranges with lower and upper bounds do not implement Exhaust because it is ambiguous whether
30// reversed ranges (e.g. 10..5) should be supported: they are undesirable for “iterate over all
31// powersets of T that are contiguous ranges” and desirable for “iterate over all values that
32// could possibly be encountered”.
33//
34// The range types with one or zero endpoints do not have this problem.
35//
36// impl<T> !Exhaust for ops::Range<T> {}
37// impl<T> !Exhaust for ops::RangeInclusive<T> {}
38
39impl<T: Exhaust> Exhaust for ops::RangeFrom<T> {
40    delegate_factory_and_iter!(T);
41
42    fn from_factory(factory: Self::Factory) -> Self {
43        ops::RangeFrom {
44            start: T::from_factory(factory),
45        }
46    }
47}
48
49impl_singleton!([], ops::RangeFull);
50
51impl<T: Exhaust> Exhaust for ops::RangeTo<T> {
52    delegate_factory_and_iter!(T);
53
54    fn from_factory(factory: Self::Factory) -> Self {
55        ops::RangeTo {
56            end: T::from_factory(factory),
57        }
58    }
59}
60
61impl<T: Exhaust> Exhaust for ops::RangeToInclusive<T> {
62    delegate_factory_and_iter!(T);
63
64    fn from_factory(factory: Self::Factory) -> Self {
65        ops::RangeToInclusive {
66            end: T::from_factory(factory),
67        }
68    }
69}
70
71/// Like the Serde “remote derive” pattern, we define a type imitating the real type
72/// which the derive macro can process.
73mod remote {
74    #![allow(missing_debug_implementations)] // not actually public
75
76    #[derive(crate::Exhaust)]
77    pub enum ControlFlow<B, C> {
78        Continue(C),
79        Break(B),
80    }
81
82    #[derive(crate::Exhaust)]
83    pub enum Bound<T> {
84        Included(T),
85        Excluded(T),
86        Unbounded,
87    }
88}