|
1 | 1 | //! Interleaves or de-interleaves paired FastQ or FASTA files. |
2 | 2 |
|
3 | 3 | use crate::{ |
4 | | - io::{ |
5 | | - DispatchFastX, InputOptions, OutputOptions, RecordWriters, WriteFileZipStdout, WriteRecord, WriteRecords, |
6 | | - check_distinct_files, |
7 | | - }, |
| 4 | + io::{DispatchFastX, InputOptions, OutputOptions, RecordWriters, WriteRecords, check_distinct_files}, |
8 | 5 | utils::paired_reads::{DeinterleavedPairedReadsExt, ZipPairedReadsExt}, |
9 | 6 | }; |
10 | 7 | use clap::Args; |
11 | 8 | use std::path::PathBuf; |
12 | | -use zoe::data::records::HeaderReadable; |
13 | 9 |
|
14 | 10 | #[derive(Args, Debug)] |
15 | 11 | pub struct XleaveArgs { |
@@ -46,61 +42,54 @@ pub fn xleave_process(args: XleaveArgs) -> Result<(), std::io::Error> { |
46 | 42 | .use_file_zip_or_stdout() |
47 | 43 | .open()?; |
48 | 44 |
|
49 | | - match (readers.reader1.dispatch(), readers.reader2.map(|x| x.dispatch())) { |
50 | | - (DispatchFastX::Fastq(reader), None) => match writer { |
51 | | - RecordWriters::SingleEnd(_) => { |
52 | | - return Err(std::io::Error::other( |
53 | | - "One input and one output were provided. No interleaving or de-interleaving can occur.", |
54 | | - )); |
55 | | - } |
56 | | - RecordWriters::PairedEnd(_) => handle_single_input(reader, writer)?, |
57 | | - }, |
58 | | - (DispatchFastX::Fastq(reader1), Some(DispatchFastX::Fastq(reader2))) => match writer { |
59 | | - RecordWriters::SingleEnd(_) => reader1.zip_paired_reads(reader2).write_records(writer)?, |
60 | | - RecordWriters::PairedEnd(_) => { |
61 | | - return Err(std::io::Error::other( |
62 | | - "Two inputs and two outputs were provided. No interleaving or de-interleaving can occur.", |
63 | | - )); |
64 | | - } |
65 | | - }, |
66 | | - (DispatchFastX::Fasta(reader), None) => match writer { |
67 | | - RecordWriters::SingleEnd(_) => { |
| 45 | + let reader1 = readers.reader1; |
| 46 | + let input_path1 = args.input_file1; |
| 47 | + |
| 48 | + if let Some((reader2, input_path2)) = readers.reader2.zip(args.input_file2) { |
| 49 | + let RecordWriters::SingleEnd(writer) = writer else { |
| 50 | + return Err(std::io::Error::other( |
| 51 | + "Two inputs and two outputs were provided. No interleaving or de-interleaving can occur.", |
| 52 | + )); |
| 53 | + }; |
| 54 | + |
| 55 | + match (reader1.dispatch(), reader2.dispatch()) { |
| 56 | + (DispatchFastX::Fastq(reader1), DispatchFastX::Fastq(reader2)) => reader1 |
| 57 | + .zip_paired_reads(reader2) |
| 58 | + .map(|res| res.map_err(|e| e.add_path_context(&input_path1, &input_path2))) |
| 59 | + .write_records(writer)?, |
| 60 | + (DispatchFastX::Fasta(reader1), DispatchFastX::Fasta(reader2)) => reader1 |
| 61 | + .zip_paired_reads(reader2) |
| 62 | + .map(|res| res.map_err(|e| e.add_path_context(&input_path1, &input_path2))) |
| 63 | + .write_records(writer)?, |
| 64 | + (DispatchFastX::Fastq(_), DispatchFastX::Fasta(_)) => { |
68 | 65 | return Err(std::io::Error::other( |
69 | | - "One input and one output were provided. No interleaving or de-interleaving can occur.", |
| 66 | + "Paired read inputs must be both FASTQ or both FASTA. Found FASTQ for first input and FASTA for second input.", |
70 | 67 | )); |
71 | 68 | } |
72 | | - RecordWriters::PairedEnd(_) => handle_single_input(reader, writer)?, |
73 | | - }, |
74 | | - (DispatchFastX::Fasta(reader1), Some(DispatchFastX::Fasta(reader2))) => match writer { |
75 | | - RecordWriters::SingleEnd(_) => reader1.zip_paired_reads(reader2).write_records(writer)?, |
76 | | - RecordWriters::PairedEnd(_) => { |
| 69 | + (DispatchFastX::Fasta(_), DispatchFastX::Fastq(_)) => { |
77 | 70 | return Err(std::io::Error::other( |
78 | | - "Two inputs and two outputs were provided. No interleaving or de-interleaving can occur.", |
| 71 | + "Paired read inputs must be both FASTQ or both FASTA. Found FASTA for first input and FASTQ for second input.", |
79 | 72 | )); |
80 | 73 | } |
81 | | - }, |
82 | | - (DispatchFastX::Fastq(_), Some(DispatchFastX::Fasta(_))) => { |
83 | | - return Err(std::io::Error::other( |
84 | | - "Paired read inputs must be both FASTQ or both FASTA. Found FASTQ for first input and FASTA for second input.", |
85 | | - )); |
86 | 74 | } |
87 | | - (DispatchFastX::Fasta(_), Some(DispatchFastX::Fastq(_))) => { |
| 75 | + } else { |
| 76 | + let RecordWriters::PairedEnd(writer) = writer else { |
88 | 77 | return Err(std::io::Error::other( |
89 | | - "Paired read inputs must be both FASTQ or both FASTA. Found FASTA for first input and FASTQ for second input.", |
| 78 | + "One input and one output were provided. No interleaving or de-interleaving can occur.", |
90 | 79 | )); |
| 80 | + }; |
| 81 | + |
| 82 | + match reader1.dispatch() { |
| 83 | + DispatchFastX::Fastq(reader) => reader |
| 84 | + .deinterleave() |
| 85 | + .map(|res| res.map_err(|e| e.add_path_context(&input_path1))) |
| 86 | + .write_records(writer)?, |
| 87 | + DispatchFastX::Fasta(reader) => reader |
| 88 | + .deinterleave() |
| 89 | + .map(|res| res.map_err(|e| e.add_path_context(&input_path1))) |
| 90 | + .write_records(writer)?, |
91 | 91 | } |
92 | 92 | } |
93 | 93 |
|
94 | 94 | Ok(()) |
95 | 95 | } |
96 | | - |
97 | | -fn handle_single_input<R1, A>(reader: R1, writer: RecordWriters<WriteFileZipStdout>) -> std::io::Result<()> |
98 | | -where |
99 | | - R1: Iterator<Item = std::io::Result<A>>, |
100 | | - A: HeaderReadable + WriteRecord<WriteFileZipStdout>, |
101 | | - std::io::Result<A>: WriteRecord<WriteFileZipStdout>, { |
102 | | - match writer { |
103 | | - RecordWriters::SingleEnd(writer) => reader.write_records(writer), |
104 | | - RecordWriters::PairedEnd(writer) => reader.deinterleave().write_records(writer), |
105 | | - } |
106 | | -} |
0 commit comments