1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
pub use ;
/// A type that can be turned into the enum of its sealed trait.
///
/// [`enumerate`] implements this for every permitted type, and makes `Enumerable<TheSealedTrait>` a
/// supertrait of the sealed trait. Naming the enum in the bound is what lets a caller reach it
/// through the trait alone:
///
/// ```
/// # use closed_trait::{enumerate, sealed};
///
/// struct Square;
///
/// #[enumerate]
/// #[sealed(Square)]
/// trait Shape {}
///
/// impl Shape for Square {}
///
/// // No import: the supertrait bound carries `into_enum` in with `S: Shape`.
/// fn describe<S: Shape>(s: S) {
/// match s.into_enum() {
/// AnyShape::Square(s) => { /* .. */ }
/// }
/// }
/// # fn main() { describe(Square); }
/// ```
///
/// Note that `Enumerable` did not have to be imported above: the supertrait bound brings
/// `into_enum` into scope through `S: TheSealedTrait`. Calling it on a concrete type rather than a
/// generic one does need the import.
///
/// `From` is implemented alongside it in the other direction, so `From::from` and `Into::into` work
/// too.
/// A type that can lend itself to the *borrowing* enum of its sealed trait.
///
/// [`enumerate`] implements this for every permitted type and makes
/// `for<'a> EnumerableRef<'a, TheSealedTraitRef<'a>>` a supertrait. The lifetime is a parameter of
/// the trait rather than of the method, so the higher-ranked bound is nameable in the supertrait
/// list, which is what lets a caller reach the enum from a plain `&S`:
///
/// ```
/// # use closed_trait::{enumerate, sealed};
/// # use closed_trait::EnumerableRef;
///
/// struct Square;
///
/// #[enumerate]
/// #[sealed(Square)]
/// trait Shape {}
///
/// impl Shape for Square {}
///
/// # fn main() {
/// let s = □
/// match s.as_enum_ref() {
/// AnyShapeRef::Square(s) => { /* .. */ }
/// }
/// # }
/// ```
///
/// [`Enumerable`] cannot do this: `into_enum` takes `self`, so reaching the owned enum means owning
/// the value. The borrowing enum is also the cheaper one to pass, being a pointer and a discriminant
/// rather than as large as the biggest permitted type.
/// A type that can lend itself *mutably* to the borrowing enum of its sealed trait.
///
/// The counterpart of [`EnumerableRef`], reached from a `&mut S` the same way:
///
/// ```
/// # use closed_trait::{enumerate, sealed};
/// # use closed_trait::EnumerableMut;
///
/// struct Square;
///
/// #[enumerate]
/// #[sealed(Square)]
/// trait Shape {}
///
/// impl Shape for Square {}
///
/// # fn main() {
/// let mut s = &mut Square;
/// match s.as_enum_mut() {
/// AnyShapeMut::Square(s) => { /* .. */ }
/// }
/// # }
/// ```
///
/// Unlike the shared enum this one is neither `Clone` nor `Copy`, a unique reference being neither.