1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use crate::utils::{error, revcomp, stdin, translate};
use anyhow::{bail, Result};
use bio::io::fasta;
use std::fmt;
use std::io;
enum Orientation {
Forward,
Reverse,
}
impl fmt::Display for Orientation {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self {
Orientation::Forward => write!(f, "forward"),
Orientation::Reverse => write!(f, "reverse"),
}
}
}
pub fn six_frame_translate(matches: &clap::ArgMatches) -> Result<()> {
let input_file = crate::get_fasta_files(matches);
let mut writer = fasta::Writer::new(io::stdout());
match input_file {
// read directly from files
Some(f) => {
for el in f.iter() {
let basename = crate::get_basename_from_pathbuf(el)?;
let reader = fasta::Reader::from_file(el).expect("[-]\tPath invalid.");
for record in reader.records() {
// now we iterate over forward/reverse
let r = record?.clone();
for strand in [Orientation::Forward, Orientation::Reverse] {
for skip in 0..=2 {
match strand {
Orientation::Forward => {
let id = r.id();
let seq = &r.seq()[skip..];
writer
.write(
&format!("{}-strand:{}-skip:{}", id, strand, skip),
Some(&basename),
&translate::translate(seq),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
Orientation::Reverse => {
let id = r.id();
let seq = &revcomp::reverse_complement(r.seq())[skip..];
writer
.write(
&format!("{}-strand:{}-skip:{}", id, strand, skip),
Some(&basename),
&translate::translate(seq),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
}
}
// write to stdout
}
}
}
// read from stdin
None => match stdin::is_stdin() {
true => {
let mut records = fasta::Reader::new(io::stdin()).records();
while let Some(Ok(record)) = records.next() {
// now we iterate over forward/reverse
let r = record.clone();
for strand in [Orientation::Forward, Orientation::Reverse] {
for skip in 0..=2 {
match strand {
Orientation::Forward => {
let id = r.id();
let seq = &r.seq()[skip..];
writer
.write(
&format!("{}-strand:{}-skip:{}", id, strand, skip),
None,
&translate::translate(seq),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
Orientation::Reverse => {
let id = r.id();
let seq = &revcomp::reverse_complement(r.seq())[skip..];
writer
.write(
&format!("{}-strand:{}-skip:{}", id, strand, skip),
None,
&translate::translate(seq),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
}
}
}
}
false => {
bail!(error::StdinError::NoSequence);
}
},
}
Ok(())
}