129 lines
3.4 KiB
Rust
129 lines
3.4 KiB
Rust
use crate::solutions;
|
|
use std::{fs, io};
|
|
|
|
pub const AMINO_ACID_MASS_TABLE: [(char, f64); 20] = [
|
|
('A', 71.03711),
|
|
('C', 103.00919),
|
|
('D', 115.02694),
|
|
('E', 129.04259),
|
|
('F', 147.06841),
|
|
('G', 57.02146),
|
|
('H', 137.05891),
|
|
('I', 113.08406),
|
|
('K', 128.09496),
|
|
('L', 113.08406),
|
|
('M', 131.04049),
|
|
('N', 114.04293),
|
|
('P', 97.05276),
|
|
('Q', 128.05858),
|
|
('R', 156.10111),
|
|
('S', 87.03203),
|
|
('T', 101.04768),
|
|
('V', 99.06841),
|
|
('W', 186.07931),
|
|
('Y', 163.06333),
|
|
];
|
|
|
|
pub struct FastaRecord {
|
|
pub id: String,
|
|
pub sequence: String,
|
|
}
|
|
|
|
#[derive(clap::ValueEnum, Clone, Debug)]
|
|
pub enum Problem {
|
|
REVP,
|
|
PRTM,
|
|
IEV,
|
|
LIA,
|
|
BINS,
|
|
MAJ,
|
|
}
|
|
|
|
pub fn run_solution(problem: Problem, in_file: &String, out_file: &String) {
|
|
// parse the input file into a string
|
|
let solution: io::Result<String> = match fs::read_to_string(in_file) {
|
|
Ok(content) => match problem {
|
|
Problem::REVP => Ok(solutions::revp(content)),
|
|
Problem::PRTM => Ok(solutions::prtm(content)),
|
|
Problem::IEV => Ok(solutions::iev(content)),
|
|
Problem::LIA => Ok(solutions::lia(content)),
|
|
Problem::BINS => Ok(solutions::bins(content)),
|
|
Problem::MAJ => Ok(solutions::maj(content)),
|
|
},
|
|
Err(e) => Err(e),
|
|
};
|
|
|
|
match solution {
|
|
Ok(out_content) => match fs::write(out_file, &out_content) {
|
|
Ok(_) => println!("{:?}", out_content),
|
|
Err(e) => println!("Error writing to output file: {e}"),
|
|
},
|
|
Err(e) => println!("An error occured reading the input file: {e}"),
|
|
};
|
|
}
|
|
|
|
pub fn read_fasta(file_content: &String) -> Vec<FastaRecord> {
|
|
let mut records: Vec<FastaRecord> = Vec::new();
|
|
let mut id = String::new();
|
|
let mut sequence = String::new();
|
|
|
|
for line in file_content.lines() {
|
|
if line.starts_with('>') {
|
|
if !id.is_empty() {
|
|
records.push(FastaRecord {
|
|
id: id.clone(),
|
|
sequence: sequence.clone(),
|
|
});
|
|
id.clear();
|
|
sequence.clear();
|
|
}
|
|
id = line[1..].to_string();
|
|
} else {
|
|
sequence.push_str(line);
|
|
}
|
|
}
|
|
records.push(FastaRecord {
|
|
id: id.clone(),
|
|
sequence: sequence.clone(),
|
|
});
|
|
records
|
|
}
|
|
|
|
pub fn get_dna_complement(dna: &String) -> String {
|
|
let mut complement = String::new();
|
|
for base in dna.chars() {
|
|
match base {
|
|
'A' => complement.push('T'),
|
|
'T' => complement.push('A'),
|
|
'C' => complement.push('G'),
|
|
'G' => complement.push('C'),
|
|
_ => panic!("Invalid DNA base"),
|
|
}
|
|
}
|
|
complement
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_read_fasta() {
|
|
let file_content =
|
|
">Rosalind_1\nGATTACA\nGTACACACACATTTTTGG\n>Rosalind_2\nTACG\n".to_string();
|
|
let records = read_fasta(&file_content);
|
|
assert_eq!(records.len(), 2);
|
|
assert_eq!(records[0].id, "Rosalind_1");
|
|
assert_eq!(records[0].sequence, "GATTACAGTACACACACATTTTTGG");
|
|
assert_eq!(records[1].id, "Rosalind_2");
|
|
assert_eq!(records[1].sequence, "TACG");
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_dna_complement() {
|
|
let dna = "GATTACA".to_string();
|
|
let expected = "CTAATGT".to_string();
|
|
assert_eq!(get_dna_complement(&dna), expected);
|
|
}
|
|
}
|