1use std::io::{self, BufRead, ErrorKind, Write};
6
7use serde::ser::Serialize;
8
9use crate::errors::BrrrrError;
10use crate::types::FastaRecord;
11use crate::types::FastqRecord;
12use crate::types::GffRecord;
13use crate::writer;
14
15use writer::RecordWriter;
16
17use noodles::fasta;
18use noodles::fastq;
19use noodles::gff;
20
21pub struct JsonRecordWriter<W: Write> {
23 writer: W,
24}
25
26impl<W: Write> JsonRecordWriter<W> {
27 pub fn new(w: W) -> Self {
29 Self { writer: w }
30 }
31}
32
33impl<W: Write> writer::RecordWriter for JsonRecordWriter<W> {
34 fn write_serde_record<S: Serialize>(&mut self, r: S) -> io::Result<()> {
36 serde_json::to_writer(&mut self.writer, &r)?;
37 self.writer.write_all(b"\n")?;
38
39 Ok(())
40 }
41}
42
43pub fn fq2jsonl<R: BufRead, W: Write>(input: R, output: &mut W) -> Result<(), BrrrrError> {
50 let mut reader = fastq::Reader::new(input);
51 let record_writer = &mut JsonRecordWriter::new(output);
52
53 for read_record in reader.records() {
54 let record = read_record?;
55 let write_op = record_writer.write_serde_record(FastqRecord::from(record));
56
57 if let Err(e) = write_op {
58 match e.kind() {
59 ErrorKind::BrokenPipe => break,
60 _ => return Err(BrrrrError::from(e)),
61 }
62 }
63 }
64 Ok(())
65}
66
67pub fn fa2jsonl<R: BufRead, W: Write>(input: R, output: &mut W) -> Result<(), BrrrrError> {
74 let mut reader = fasta::Reader::new(input);
75 let record_writer = &mut JsonRecordWriter::new(output);
76
77 for read_record in reader.records() {
78 let record = read_record?;
79 let write_op = record_writer.write_serde_record(FastaRecord::from(record));
80
81 if let Err(e) = write_op {
82 match e.kind() {
83 ErrorKind::BrokenPipe => break,
84 _ => return Err(BrrrrError::from(e)),
85 }
86 }
87 }
88 Ok(())
89}
90
91pub fn gff2jsonl<R: BufRead, W: Write>(input: R, output: &mut W) -> Result<(), BrrrrError> {
98 let mut reader = gff::Reader::new(input);
99 let record_writer = &mut JsonRecordWriter::new(output);
100
101 for read_record in reader.records() {
102 let record = read_record?;
103 let write_op = record_writer.write_serde_record(GffRecord::from(record));
104
105 if let Err(e) = write_op {
106 match e.kind() {
107 ErrorKind::BrokenPipe => break,
108 _ => return Err(BrrrrError::from(e)),
109 }
110 }
111 }
112 Ok(())
113}
114
115#[cfg(test)]
116mod tests {
117 use super::*;
118
119 #[test]
120 fn test_fa2jsonl() {
121 let input = b">A\nATCG\n" as &[u8];
122
123 let mut output = Vec::new();
124 fa2jsonl(input, &mut output).unwrap();
125
126 let output_str = String::from_utf8(output).unwrap();
127 let expected_output = "{\"id\":\"A\",\"desc\":null,\"seq\":\"ATCG\"}\n".to_string();
128 assert_eq!(output_str, expected_output);
129 }
130}