1 module dhtslib.fastq;
2 import dhtslib.bgzf;
3 import std.range.interfaces : InputRange, inputRangeObject; 
4 
5 /*
6  *  Represents a complete fastq read record.
7  */ 
8 struct FastqRecord
9 {
10     string id;
11     string sequence;
12     string extra;
13     string qscores;
14 }
15 
16 /*
17  *  Parses a bgzipped, gzipped, or plain-text fastq file 
18  *  into a range of FastqRecords.
19  */ 
20 struct FastqFile
21 {
22     BGZFile f;
23     InputRange!string lines;
24     FastqRecord rec;
25     bool last;
26 
27     this(string fn)
28     {
29         f = BGZFile(fn);
30         lines = f.byLineCopy.inputRangeObject;
31         popFront;
32     }
33 
34     /// Explicit postblit to avoid 
35     /// https://github.com/blachlylab/dhtslib/issues/122
36     this(this)
37     {
38         this.f = f;
39         this.lines = lines;
40         this.rec = rec;
41         this.last = last;
42     }
43 
44     FastqRecord front()
45     {
46         return rec;
47     }
48 
49     void popFront()
50     {
51         //get id line
52         rec.id = lines.front;
53         lines.popFront;
54 
55         //get seq line
56         rec.sequence = lines.front;
57         lines.popFront;
58 
59         //get extra line
60         rec.extra = lines.front;
61         lines.popFront;
62 
63         //get qscore line
64         rec.qscores = lines.front;
65         if(!lines.empty)
66             lines.popFront;
67         else
68             last = true;
69     }
70 
71     bool empty()
72     {
73         return lines.empty && last;
74     }
75 
76 }
77 
78 ///
79 debug(dhtslib_unittest) unittest
80 {
81     import std.stdio;
82     import htslib.hts_log;
83     import std.algorithm : map;
84     import std.array : array;
85     import std.path : buildPath,dirName;
86     hts_set_log_level(htsLogLevel.HTS_LOG_INFO);
87     hts_log_info(__FUNCTION__, "Testing FastqFile");
88     hts_log_info(__FUNCTION__, "Loading test file");
89 
90     auto fqs = FastqFile(buildPath(dirName(dirName(dirName(__FILE__))),"htslib","test","fastqs.fq"));
91     assert(fqs.array.length == 125);
92     // assert(bg.array == ["122333444455555"]);
93 }