1use std::ops::BitOr;
12
13#[derive(Debug, Clone, Copy, Default)]
15pub struct Name;
16
17#[derive(Debug, Clone, Copy, Default)]
19pub struct Sequence;
20
21#[derive(Debug, Clone, Copy, Default)]
23pub struct Quality;
24
25#[derive(Debug, Clone, Copy, Default)]
27pub struct Key;
28
29#[derive(Debug, Clone, Copy, Default)]
31pub struct NameSequence;
32
33#[derive(Debug, Clone, Copy, Default)]
35pub struct NameQuality;
36
37#[derive(Debug, Clone, Copy, Default)]
39pub struct NameKey;
40
41#[derive(Debug, Clone, Copy, Default)]
43pub struct SequenceQuality;
44
45#[derive(Debug, Clone, Copy, Default)]
47pub struct SequenceKey;
48
49#[derive(Debug, Clone, Copy, Default)]
51pub struct QualityKey;
52
53#[derive(Debug, Clone, Copy, Default)]
55pub struct NameSequenceQuality;
56
57#[derive(Debug, Clone, Copy, Default)]
59pub struct NameSequenceKey;
60
61#[derive(Debug, Clone, Copy, Default)]
63pub struct NameQualityKey;
64
65#[derive(Debug, Clone, Copy, Default)]
67pub struct SequenceQualityKey;
68
69#[derive(Debug, Clone, Copy, Default)]
71pub struct AllFields;
72
73pub trait SelectionExpr: private::Sealed + Copy {}
78
79#[doc(hidden)]
81pub trait SelectionPlan: SelectionExpr {
82 const NEEDS_NAME: bool;
83 const NEEDS_SEQUENCE: bool;
84 const NEEDS_QUALITY: bool;
85 const NEEDS_KEY: bool;
86}
87
88macro_rules! impl_selection_expr {
89 ($($ty:ty),* $(,)?) => { $(impl SelectionExpr for $ty {})* };
90}
91
92impl_selection_expr!(
93 Name,
94 Sequence,
95 Quality,
96 Key,
97 NameSequence,
98 NameQuality,
99 NameKey,
100 SequenceQuality,
101 SequenceKey,
102 QualityKey,
103 NameSequenceQuality,
104 NameSequenceKey,
105 NameQualityKey,
106 SequenceQualityKey,
107 AllFields,
108);
109
110#[doc(hidden)]
111pub trait HasName: SelectionExpr {}
112
113#[doc(hidden)]
114pub trait HasSequence: SelectionExpr {}
115
116#[doc(hidden)]
117pub trait HasQuality: SelectionExpr {}
118
119#[doc(hidden)]
120pub trait HasKey: SelectionExpr {}
121
122macro_rules! impl_selection_plan {
123 ($ty:ty, $name:expr, $sequence:expr, $quality:expr, $key:expr) => {
124 impl SelectionPlan for $ty {
125 const NEEDS_NAME: bool = $name;
126 const NEEDS_SEQUENCE: bool = $sequence;
127 const NEEDS_QUALITY: bool = $quality;
128 const NEEDS_KEY: bool = $key;
129 }
130 };
131}
132
133impl_selection_plan!(Name, true, false, false, false);
134impl_selection_plan!(Sequence, false, true, false, false);
135impl_selection_plan!(Quality, false, false, true, false);
136impl_selection_plan!(Key, false, false, false, true);
137impl_selection_plan!(NameSequence, true, true, false, false);
138impl_selection_plan!(NameQuality, true, false, true, false);
139impl_selection_plan!(NameKey, true, false, false, true);
140impl_selection_plan!(SequenceQuality, false, true, true, false);
141impl_selection_plan!(SequenceKey, false, true, false, true);
142impl_selection_plan!(QualityKey, false, false, true, true);
143impl_selection_plan!(NameSequenceQuality, true, true, true, false);
144impl_selection_plan!(NameSequenceKey, true, true, false, true);
145impl_selection_plan!(NameQualityKey, true, false, true, true);
146impl_selection_plan!(SequenceQualityKey, false, true, true, true);
147impl_selection_plan!(AllFields, true, true, true, true);
148
149macro_rules! impl_has_name {
150 ($($ty:ty),* $(,)?) => { $(impl HasName for $ty {})* };
151}
152
153macro_rules! impl_has_sequence {
154 ($($ty:ty),* $(,)?) => { $(impl HasSequence for $ty {})* };
155}
156
157macro_rules! impl_has_quality {
158 ($($ty:ty),* $(,)?) => { $(impl HasQuality for $ty {})* };
159}
160
161macro_rules! impl_has_key {
162 ($($ty:ty),* $(,)?) => { $(impl HasKey for $ty {})* };
163}
164
165impl_has_name!(
166 Name,
167 NameSequence,
168 NameQuality,
169 NameKey,
170 NameSequenceQuality,
171 NameSequenceKey,
172 NameQualityKey,
173 AllFields,
174);
175
176impl_has_sequence!(
177 Sequence,
178 NameSequence,
179 SequenceQuality,
180 SequenceKey,
181 NameSequenceQuality,
182 NameSequenceKey,
183 SequenceQualityKey,
184 AllFields,
185);
186
187impl_has_quality!(
188 Quality,
189 NameQuality,
190 SequenceQuality,
191 QualityKey,
192 NameSequenceQuality,
193 NameQualityKey,
194 SequenceQualityKey,
195 AllFields,
196);
197
198impl_has_key!(
199 Key,
200 NameKey,
201 SequenceKey,
202 QualityKey,
203 NameSequenceKey,
204 NameQualityKey,
205 SequenceQualityKey,
206 AllFields,
207);
208
209macro_rules! impl_bitor {
210 ($lhs:ty, $rhs:ty => $out:ty) => {
211 impl BitOr<$rhs> for $lhs {
212 type Output = $out;
213
214 fn bitor(self, _rhs: $rhs) -> Self::Output {
215 <$out>::default()
216 }
217 }
218 };
219}
220
221impl_bitor!(Name, Name => Name);
222impl_bitor!(Sequence, Sequence => Sequence);
223impl_bitor!(Quality, Quality => Quality);
224impl_bitor!(Key, Key => Key);
225
226impl_bitor!(Name, Sequence => NameSequence);
227impl_bitor!(Sequence, Name => NameSequence);
228impl_bitor!(Name, Quality => NameQuality);
229impl_bitor!(Quality, Name => NameQuality);
230impl_bitor!(Name, Key => NameKey);
231impl_bitor!(Key, Name => NameKey);
232impl_bitor!(Sequence, Quality => SequenceQuality);
233impl_bitor!(Quality, Sequence => SequenceQuality);
234impl_bitor!(Sequence, Key => SequenceKey);
235impl_bitor!(Key, Sequence => SequenceKey);
236impl_bitor!(Quality, Key => QualityKey);
237impl_bitor!(Key, Quality => QualityKey);
238
239impl_bitor!(NameSequence, Name => NameSequence);
240impl_bitor!(Name, NameSequence => NameSequence);
241impl_bitor!(NameSequence, Quality => NameSequenceQuality);
242impl_bitor!(Quality, NameSequence => NameSequenceQuality);
243impl_bitor!(NameSequence, Key => NameSequenceKey);
244impl_bitor!(Key, NameSequence => NameSequenceKey);
245
246impl_bitor!(NameQuality, Name => NameQuality);
247impl_bitor!(Name, NameQuality => NameQuality);
248impl_bitor!(NameQuality, Sequence => NameSequenceQuality);
249impl_bitor!(Sequence, NameQuality => NameSequenceQuality);
250impl_bitor!(NameQuality, Key => NameQualityKey);
251impl_bitor!(Key, NameQuality => NameQualityKey);
252
253impl_bitor!(NameKey, Name => NameKey);
254impl_bitor!(Name, NameKey => NameKey);
255impl_bitor!(NameKey, Sequence => NameSequenceKey);
256impl_bitor!(Sequence, NameKey => NameSequenceKey);
257impl_bitor!(NameKey, Quality => NameQualityKey);
258impl_bitor!(Quality, NameKey => NameQualityKey);
259
260impl_bitor!(SequenceQuality, Sequence => SequenceQuality);
261impl_bitor!(Sequence, SequenceQuality => SequenceQuality);
262impl_bitor!(SequenceQuality, Name => NameSequenceQuality);
263impl_bitor!(Name, SequenceQuality => NameSequenceQuality);
264impl_bitor!(SequenceQuality, Key => SequenceQualityKey);
265impl_bitor!(Key, SequenceQuality => SequenceQualityKey);
266
267impl_bitor!(SequenceKey, Sequence => SequenceKey);
268impl_bitor!(Sequence, SequenceKey => SequenceKey);
269impl_bitor!(SequenceKey, Name => NameSequenceKey);
270impl_bitor!(Name, SequenceKey => NameSequenceKey);
271impl_bitor!(SequenceKey, Quality => SequenceQualityKey);
272impl_bitor!(Quality, SequenceKey => SequenceQualityKey);
273
274impl_bitor!(QualityKey, Quality => QualityKey);
275impl_bitor!(Quality, QualityKey => QualityKey);
276impl_bitor!(QualityKey, Name => NameQualityKey);
277impl_bitor!(Name, QualityKey => NameQualityKey);
278impl_bitor!(QualityKey, Sequence => SequenceQualityKey);
279impl_bitor!(Sequence, QualityKey => SequenceQualityKey);
280
281impl_bitor!(NameSequenceQuality, Name => NameSequenceQuality);
282impl_bitor!(Name, NameSequenceQuality => NameSequenceQuality);
283impl_bitor!(NameSequenceQuality, Sequence => NameSequenceQuality);
284impl_bitor!(Sequence, NameSequenceQuality => NameSequenceQuality);
285impl_bitor!(NameSequenceQuality, Quality => NameSequenceQuality);
286impl_bitor!(Quality, NameSequenceQuality => NameSequenceQuality);
287impl_bitor!(NameSequenceQuality, Key => AllFields);
288impl_bitor!(Key, NameSequenceQuality => AllFields);
289
290impl_bitor!(NameSequenceKey, Name => NameSequenceKey);
291impl_bitor!(Name, NameSequenceKey => NameSequenceKey);
292impl_bitor!(NameSequenceKey, Sequence => NameSequenceKey);
293impl_bitor!(Sequence, NameSequenceKey => NameSequenceKey);
294impl_bitor!(NameSequenceKey, Key => NameSequenceKey);
295impl_bitor!(Key, NameSequenceKey => NameSequenceKey);
296impl_bitor!(NameSequenceKey, Quality => AllFields);
297impl_bitor!(Quality, NameSequenceKey => AllFields);
298
299impl_bitor!(NameQualityKey, Name => NameQualityKey);
300impl_bitor!(Name, NameQualityKey => NameQualityKey);
301impl_bitor!(NameQualityKey, Quality => NameQualityKey);
302impl_bitor!(Quality, NameQualityKey => NameQualityKey);
303impl_bitor!(NameQualityKey, Key => NameQualityKey);
304impl_bitor!(Key, NameQualityKey => NameQualityKey);
305impl_bitor!(NameQualityKey, Sequence => AllFields);
306impl_bitor!(Sequence, NameQualityKey => AllFields);
307
308impl_bitor!(SequenceQualityKey, Sequence => SequenceQualityKey);
309impl_bitor!(Sequence, SequenceQualityKey => SequenceQualityKey);
310impl_bitor!(SequenceQualityKey, Quality => SequenceQualityKey);
311impl_bitor!(Quality, SequenceQualityKey => SequenceQualityKey);
312impl_bitor!(SequenceQualityKey, Key => SequenceQualityKey);
313impl_bitor!(Key, SequenceQualityKey => SequenceQualityKey);
314impl_bitor!(SequenceQualityKey, Name => AllFields);
315impl_bitor!(Name, SequenceQualityKey => AllFields);
316
317impl_bitor!(AllFields, Name => AllFields);
318impl_bitor!(Name, AllFields => AllFields);
319impl_bitor!(AllFields, Sequence => AllFields);
320impl_bitor!(Sequence, AllFields => AllFields);
321impl_bitor!(AllFields, Quality => AllFields);
322impl_bitor!(Quality, AllFields => AllFields);
323impl_bitor!(AllFields, Key => AllFields);
324impl_bitor!(Key, AllFields => AllFields);
325
326mod private {
327 pub trait Sealed {}
328
329 macro_rules! impl_sealed {
330 ($($ty:ty),* $(,)?) => { $(impl Sealed for $ty {})* };
331 }
332
333 impl_sealed!(
334 super::Name,
335 super::Sequence,
336 super::Quality,
337 super::Key,
338 super::NameSequence,
339 super::NameQuality,
340 super::NameKey,
341 super::SequenceQuality,
342 super::SequenceKey,
343 super::QualityKey,
344 super::NameSequenceQuality,
345 super::NameSequenceKey,
346 super::NameQualityKey,
347 super::SequenceQualityKey,
348 super::AllFields,
349 );
350}
351
352#[cfg(test)]
353mod tests {
354 use super::{
355 AllFields, HasKey, HasName, HasQuality, HasSequence, Key, Name, NameSequence,
356 NameSequenceQuality, Quality, QualityKey, SelectionExpr, Sequence, SequenceKey,
357 };
358
359 fn assert_selection_expr<T: SelectionExpr>(_value: T) {}
360 fn assert_has_name<T: HasName>(_value: T) {}
361 fn assert_has_sequence<T: HasSequence>(_value: T) {}
362 fn assert_has_quality<T: HasQuality>(_value: T) {}
363 fn assert_has_key<T: HasKey>(_value: T) {}
364
365 #[test]
366 fn field_markers_compose_into_selection_sets() {
367 let seq_key = Sequence | Key;
368 let key_seq = Key | Sequence;
369 let _: SequenceKey = seq_key;
370 let _: SequenceKey = key_seq;
371
372 let all = Sequence | Key | Quality | Name;
373 let _: AllFields = all;
374 assert_selection_expr(all);
375 }
376
377 #[test]
378 fn capability_traits_match_selected_fields() {
379 assert_has_sequence(Sequence);
380 assert_has_name(NameSequence);
381 assert_has_sequence(NameSequence);
382 assert_has_quality(NameSequenceQuality);
383 assert_has_key(QualityKey);
384 assert_has_name(AllFields);
385 assert_has_sequence(AllFields);
386 assert_has_quality(AllFields);
387 assert_has_key(AllFields);
388 }
389}