structural_typing/
presence.rs1use core::marker::PhantomData;
4
5use crate::access::Access;
6
7pub struct Present;
9pub struct Optional;
11pub struct Absent;
13
14pub trait Presence {
16 type OptionOrSelf: Presence;
18 type Or<Other: Presence>: Presence;
20 type RemainderFrom<Source: Presence>: Presence;
22 type Output<T>: Access<T>;
24
25 fn or<T, Other: Presence>(
27 self_: <Self as Presence>::Output<T>,
28 other: Other::Output<T>,
29 ) -> <<Self as Presence>::Or<Other> as Presence>::Output<T>;
30
31 fn option_or_self<T>(
33 option: Option<T>,
34 self_: <Self as Presence>::Output<T>,
35 ) -> <<Self as Presence>::OptionOrSelf as Presence>::Output<T>;
36}
37
38pub trait InferPresence<T> {
40 type Presence: Presence<Output<T> = Self>;
42}
43
44impl<T> InferPresence<T> for T {
45 type Presence = Present;
46}
47
48impl<T> InferPresence<T> for Option<T> {
49 type Presence = Optional;
50}
51
52impl<T> InferPresence<T> for PhantomData<T> {
53 type Presence = Absent;
54}
55
56impl Presence for Present {
57 type OptionOrSelf = Present;
58 type Or<Other: Presence> = Present;
59 type RemainderFrom<Source: Presence> = Absent;
60 type Output<T> = T;
61
62 #[inline]
63 fn or<T, Other: Presence>(
64 self_: <Self as Presence>::Output<T>,
65 _other: Other::Output<T>,
66 ) -> <<Self as Presence>::Or<Other> as Presence>::Output<T> {
67 self_
68 }
69
70 #[inline]
71 fn option_or_self<T>(
72 option: Option<T>,
73 self_: <Self as Presence>::Output<T>,
74 ) -> <<Self as Presence>::OptionOrSelf as Presence>::Output<T> {
75 option.unwrap_or(self_)
76 }
77}
78
79impl Presence for Optional {
80 type OptionOrSelf = Optional;
81 type Or<Other: Presence> = Other::OptionOrSelf;
82 type RemainderFrom<Source: Presence> = Absent;
83 type Output<T> = Option<T>;
84
85 #[inline]
86 fn or<T, Other: Presence>(
87 self_: <Self as Presence>::Output<T>,
88 other: Other::Output<T>,
89 ) -> <<Self as Presence>::Or<Other> as Presence>::Output<T> {
90 Other::option_or_self(self_, other)
91 }
92
93 #[inline]
94 fn option_or_self<T>(
95 option: Option<T>,
96 self_: <Self as Presence>::Output<T>,
97 ) -> <<Self as Presence>::OptionOrSelf as Presence>::Output<T> {
98 option.or(self_)
99 }
100}
101
102impl Presence for Absent {
103 type OptionOrSelf = Optional;
104 type Or<Other: Presence> = Other;
105 type RemainderFrom<Source: Presence> = Source;
106 type Output<T> = PhantomData<T>;
107
108 #[inline]
109 fn or<T, Other: Presence>(
110 _self: <Self as Presence>::Output<T>,
111 other: Other::Output<T>,
112 ) -> <<Self as Presence>::Or<Other> as Presence>::Output<T> {
113 other
114 }
115
116 #[inline]
117 fn option_or_self<T>(
118 option: Option<T>,
119 _self_: <Self as Presence>::Output<T>,
120 ) -> <<Self as Presence>::OptionOrSelf as Presence>::Output<T> {
121 option
122 }
123}