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
use crate::utils::{error, stdin};
use anyhow::{bail, Result};
use bio::io::fasta;
use std::io;
pub fn get_lengths(matches: &clap::ArgMatches) -> Result<()> {
let input_file = crate::get_fasta_files(matches);
let extract_length = matches.get_one::<usize>("extract");
let less = matches.get_flag("less");
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)?;
for record in reader.records() {
let record = record?;
let id = record.id();
let desc = record.desc().unwrap_or("");
let len = record.seq().len();
// filtering
if let Some(l) = extract_length {
let length = *l;
match less {
false => {
// default, print greater than
if len > length {
writer
.write(
id,
Some(&format!("{}:length:{}", desc, len)),
record.seq(),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
true => {
// alt, print less than
if len < length {
writer
.write(
id,
Some(&format!("{}:length:{}", desc, len)),
record.seq(),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
}
} else {
// write to stdout
println!("{}\t{}\t{}", basename, id, len);
}
}
}
}
// 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() {
let id = record.id();
let desc = record.desc().unwrap_or("");
let len = record.seq().len();
// filtering
if let Some(l) = extract_length {
let length = *l;
match less {
false => {
// default, print greater than
if len > length {
writer
.write(
id,
Some(&format!("{}:length:{}", desc, len)),
record.seq(),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
true => {
// alt, print less than
if len < length {
writer
.write(
id,
Some(&format!("{}:length:{}", desc, len)),
record.seq(),
)
.map_err(|_| error::FastaWriteError::CouldNotWrite)?;
}
}
}
} else {
// write to stdout
println!("{}\t{}", id, len);
}
}
}
false => {
bail!(error::StdinError::NoSequence)
}
},
}
Ok(())
}