fastq_chunk_sink/
fastq_chunk_sink.rs1use std::io;
2
3use dino_seq::{
4 FastqChunkConfig, FastqChunkSinkExt, FastqReader, FastqRecordSink, FastqVisitRecord, Result,
5};
6
7#[derive(Debug)]
8struct OwnedRead {
9 name: Vec<u8>,
10 seq: Vec<u8>,
11 qual: Vec<u8>,
12}
13
14#[derive(Debug, Default)]
15struct ReadBuffer {
16 reads: Vec<OwnedRead>,
17 bases: u64,
18}
19
20impl FastqRecordSink for ReadBuffer {
21 fn record(&mut self, record: FastqVisitRecord<'_>) -> Result<()> {
22 self.bases += record.seq().len() as u64;
23 self.reads.push(OwnedRead {
24 name: record.name().to_vec(),
25 seq: record.seq().to_vec(),
26 qual: record.qual().to_vec(),
27 });
28 Ok(())
29 }
30}
31
32impl FastqChunkSinkExt for ReadBuffer {
33 fn reserve_records(&mut self, records: usize) {
34 self.reads.reserve(records);
35 }
36}
37
38impl ReadBuffer {
39 fn clear(&mut self) {
40 self.reads.clear();
41 self.bases = 0;
42 }
43}
44
45fn main() -> Result<()> {
46 let stdin = io::stdin();
47 let mut reader = FastqReader::new(stdin.lock());
48 let config = FastqChunkConfig::new(10_000_000).min_records(40_000);
49 let mut sink = ReadBuffer::default();
50
51 sink.reserve_records(config.estimated_records(150));
52 while let Some(stats) = reader.next_chunk_with_sink(config, &mut sink)? {
53 let checksum: usize = sink
54 .reads
55 .iter()
56 .map(|read| read.name.len() ^ read.seq.len() ^ read.qual.len())
57 .sum();
58 eprintln!(
59 "chunk first_record={} records={} bases={} checksum={}",
60 stats.first_record_index(),
61 stats.records(),
62 stats.bases(),
63 checksum
64 );
65
66 sink.clear();
69 sink.reserve_records(config.estimated_records(150));
70 }
71
72 Ok(())
73}