1use std::ops::Range;
2
3use crate::fastq_frame;
4
5#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct RecordRef {
12 pub name: Range<u32>,
14 pub seq: Range<u32>,
16 pub plus: Range<u32>,
18 pub qual: Range<u32>,
20}
21
22#[derive(Debug, Clone, Copy)]
28pub struct FastqRecord<'a> {
29 pub(crate) bytes: &'a [u8],
30 pub(crate) record: &'a RecordRef,
31}
32
33impl<'a> FastqRecord<'a> {
34 #[inline]
36 pub fn name(self) -> &'a [u8] {
37 &self.bytes[to_usize(self.record.name.clone())]
38 }
39
40 #[inline]
42 pub fn name_without_at(self) -> &'a [u8] {
43 let name = self.name();
44 name.strip_prefix(b"@").unwrap_or(name)
45 }
46
47 #[inline]
49 pub fn id_token(self) -> &'a [u8] {
50 let name = self.name_without_at();
51 let end = name
52 .iter()
53 .position(u8::is_ascii_whitespace)
54 .unwrap_or(name.len());
55 &name[..end]
56 }
57
58 #[inline]
60 pub fn pair_normalized_id(self) -> &'a [u8] {
61 strip_pair_suffix(self.id_token())
62 }
63
64 #[inline]
66 pub fn seq(self) -> &'a [u8] {
67 &self.bytes[to_usize(self.record.seq.clone())]
68 }
69
70 #[inline]
72 pub fn plus(self) -> &'a [u8] {
73 &self.bytes[to_usize(self.record.plus.clone())]
74 }
75
76 #[inline]
78 pub fn qual(self) -> &'a [u8] {
79 &self.bytes[to_usize(self.record.qual.clone())]
80 }
81}
82
83#[derive(Debug, Clone, Copy)]
89pub struct FastqVisitRecord<'a> {
90 pub(crate) name: &'a [u8],
91 pub(crate) seq: &'a [u8],
92 pub(crate) plus: &'a [u8],
93 pub(crate) qual: &'a [u8],
94}
95
96impl<'a> FastqVisitRecord<'a> {
97 #[inline]
99 pub fn name(self) -> &'a [u8] {
100 self.name
101 }
102
103 #[inline]
105 pub fn seq(self) -> &'a [u8] {
106 self.seq
107 }
108
109 #[inline]
111 pub fn plus(self) -> &'a [u8] {
112 self.plus
113 }
114
115 #[inline]
117 pub fn qual(self) -> &'a [u8] {
118 self.qual
119 }
120}
121
122#[inline]
124pub fn strip_pair_suffix(id: &[u8]) -> &[u8] {
125 fastq_frame::strip_pair_suffix(id)
126}
127
128#[inline]
129pub(crate) fn to_u32_range(range: Range<usize>) -> Range<u32> {
130 debug_assert!(u32::try_from(range.end).is_ok());
131 range.start as u32..range.end as u32
132}
133
134#[inline]
135fn to_usize(range: Range<u32>) -> Range<usize> {
136 range.start as usize..range.end as usize
137}