1use core::marker::PhantomData;
27
28mod private {
30 pub trait Sealed {}
31}
32
33pub trait PartitionValidity: private::Sealed + Clone + Copy + Default + 'static {}
39
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
44pub struct ValidPartition;
45
46impl private::Sealed for ValidPartition {}
47impl PartitionValidity for ValidPartition {}
48
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
51pub struct UnvalidatedPartition;
52
53impl private::Sealed for UnvalidatedPartition {}
54impl PartitionValidity for UnvalidatedPartition {}
55
56pub trait TableauValidity: private::Sealed + Clone + Copy + Default + 'static {}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
65pub struct Semistandard;
66
67impl private::Sealed for Semistandard {}
68impl TableauValidity for Semistandard {}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
72pub struct LatticeWord;
73
74impl private::Sealed for LatticeWord {}
75impl TableauValidity for LatticeWord {}
76
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
79pub struct UnverifiedTableau;
80
81impl private::Sealed for UnverifiedTableau {}
82impl TableauValidity for UnverifiedTableau {}
83
84pub trait GrantState: private::Sealed + Clone + Copy + Default + 'static {}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
93pub struct Granted;
94
95impl private::Sealed for Granted {}
96impl GrantState for Granted {}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
100pub struct Pending;
101
102impl private::Sealed for Pending {}
103impl GrantState for Pending {}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
107pub struct Revoked;
108
109impl private::Sealed for Revoked {}
110impl GrantState for Revoked {}
111
112pub trait IntersectionDimension: private::Sealed + Clone + Copy + Default + 'static {}
118
119#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
123pub struct Transverse;
124
125impl private::Sealed for Transverse {}
126impl IntersectionDimension for Transverse {}
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
132pub struct Excess;
133
134impl private::Sealed for Excess {}
135impl IntersectionDimension for Excess {}
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
141pub struct Deficient;
142
143impl private::Sealed for Deficient {}
144impl IntersectionDimension for Deficient {}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
148pub struct UnknownDimension;
149
150impl private::Sealed for UnknownDimension {}
151impl IntersectionDimension for UnknownDimension {}
152
153pub trait BoxContainment: private::Sealed + Clone + Copy + Default + 'static {}
159
160#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
162pub struct FitsInBox;
163
164impl private::Sealed for FitsInBox {}
165impl BoxContainment for FitsInBox {}
166
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
169pub struct UnverifiedBox;
170
171impl private::Sealed for UnverifiedBox {}
172impl BoxContainment for UnverifiedBox {}
173
174pub type ValidLRTableau = (Semistandard, LatticeWord);
180
181pub type ValidSchubertClass = (ValidPartition, FitsInBox);
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
186pub struct Properties<T>(PhantomData<T>);
187
188impl<T> Properties<T> {
189 #[must_use]
191 pub const fn new() -> Self {
192 Self(PhantomData)
193 }
194}
195
196#[cfg(test)]
197mod tests {
198 use super::*;
199 use core::mem::size_of;
200
201 #[test]
202 fn test_phantom_types_are_zero_sized() {
203 assert_eq!(size_of::<ValidPartition>(), 0);
204 assert_eq!(size_of::<UnvalidatedPartition>(), 0);
205 assert_eq!(size_of::<Semistandard>(), 0);
206 assert_eq!(size_of::<LatticeWord>(), 0);
207 assert_eq!(size_of::<Granted>(), 0);
208 assert_eq!(size_of::<Pending>(), 0);
209 assert_eq!(size_of::<Transverse>(), 0);
210 assert_eq!(size_of::<FitsInBox>(), 0);
211 assert_eq!(size_of::<Properties<ValidLRTableau>>(), 0);
212 }
213
214 #[test]
215 fn test_phantom_types_implement_traits() {
216 fn assert_partition_validity<T: PartitionValidity>() {}
217 fn assert_tableau_validity<T: TableauValidity>() {}
218 fn assert_grant_state<T: GrantState>() {}
219 fn assert_intersection_dim<T: IntersectionDimension>() {}
220 fn assert_box_containment<T: BoxContainment>() {}
221
222 assert_partition_validity::<ValidPartition>();
223 assert_partition_validity::<UnvalidatedPartition>();
224
225 assert_tableau_validity::<Semistandard>();
226 assert_tableau_validity::<LatticeWord>();
227 assert_tableau_validity::<UnverifiedTableau>();
228
229 assert_grant_state::<Granted>();
230 assert_grant_state::<Pending>();
231 assert_grant_state::<Revoked>();
232
233 assert_intersection_dim::<Transverse>();
234 assert_intersection_dim::<Excess>();
235 assert_intersection_dim::<Deficient>();
236
237 assert_box_containment::<FitsInBox>();
238 assert_box_containment::<UnverifiedBox>();
239 }
240
241 #[test]
242 fn test_phantom_types_are_copy() {
243 let v1 = ValidPartition;
244 let v2 = v1;
245 assert_eq!(v1, v2);
246
247 let s1 = Semistandard;
248 let s2 = s1;
249 assert_eq!(s1, s2);
250 }
251}