Skip to main content

dryice/
fields.rs

1//! Field markers and selection-expression scaffolding for selected reads.
2//!
3//! The selection syntax is intentionally value-shaped for ergonomic builder
4//! calls such as `select(Sequence | Key)`, but the result carries type-level
5//! information so selected-read APIs can gate field access at compile time.
6//!
7//! Selections control selective decoding, not partial file I/O. `dryice` still
8//! reads whole blocks, but a selected reader only decodes the chosen projection
9//! for each record it advances through.
10
11use std::ops::BitOr;
12
13/// Public marker for read names.
14#[derive(Debug, Clone, Copy, Default)]
15pub struct Name;
16
17/// Public marker for sequences.
18#[derive(Debug, Clone, Copy, Default)]
19pub struct Sequence;
20
21/// Public marker for qualities.
22#[derive(Debug, Clone, Copy, Default)]
23pub struct Quality;
24
25/// Public marker for record keys.
26#[derive(Debug, Clone, Copy, Default)]
27pub struct Key;
28
29/// Selection set containing `Name | Sequence`.
30#[derive(Debug, Clone, Copy, Default)]
31pub struct NameSequence;
32
33/// Selection set containing `Name | Quality`.
34#[derive(Debug, Clone, Copy, Default)]
35pub struct NameQuality;
36
37/// Selection set containing `Name | Key`.
38#[derive(Debug, Clone, Copy, Default)]
39pub struct NameKey;
40
41/// Selection set containing `Sequence | Quality`.
42#[derive(Debug, Clone, Copy, Default)]
43pub struct SequenceQuality;
44
45/// Selection set containing `Sequence | Key`.
46#[derive(Debug, Clone, Copy, Default)]
47pub struct SequenceKey;
48
49/// Selection set containing `Quality | Key`.
50#[derive(Debug, Clone, Copy, Default)]
51pub struct QualityKey;
52
53/// Selection set containing `Name | Sequence | Quality`.
54#[derive(Debug, Clone, Copy, Default)]
55pub struct NameSequenceQuality;
56
57/// Selection set containing `Name | Sequence | Key`.
58#[derive(Debug, Clone, Copy, Default)]
59pub struct NameSequenceKey;
60
61/// Selection set containing `Name | Quality | Key`.
62#[derive(Debug, Clone, Copy, Default)]
63pub struct NameQualityKey;
64
65/// Selection set containing `Sequence | Quality | Key`.
66#[derive(Debug, Clone, Copy, Default)]
67pub struct SequenceQualityKey;
68
69/// Selection set containing all supported fields.
70#[derive(Debug, Clone, Copy, Default)]
71pub struct AllFields;
72
73/// Marker trait implemented by field-selection expressions.
74///
75/// Users normally interact with this trait indirectly through field markers
76/// such as [`Sequence`] and algebraic combinations such as `Sequence | Key`.
77pub trait SelectionExpr: private::Sealed + Copy {}
78
79/// Internal preparation plan derived from a selected field set.
80#[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}