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 = 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 { let mut records: Vec = 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); } }