use std::{collections::HashMap, fmt::Display};
use crate::prelude::*;
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Genome {
chromosomes: HashMap<String, Chromosome>,
}
impl Genome {
#[inline]
pub fn new(genes: Vec<(&str, &str, Gene)>) -> Self {
let mut genome = Self {
..Default::default()
};
genome.insert_genes(genes);
genome
}
#[inline]
pub fn chromosome(&self, chromo_name: &str) -> Option<&Chromosome> {
self.chromosomes.get(chromo_name)
}
#[inline]
pub fn gene(&self, chromo_name: &str, gene_name: &str) -> Option<&Gene> {
self.chromosome(chromo_name)?.gene(gene_name)
}
#[inline]
pub fn chromosomes(&self) -> &HashMap<String, Chromosome> {
&self.chromosomes
}
#[inline]
pub fn genes(&self) -> Vec<(&str, &str, Gene)> {
let mut genes = Vec::default();
for chromo in self.chromosomes() {
for gene in chromo.1.genes() {
genes.push((chromo.0.as_str(), gene.0.as_str(), gene.1.clone()));
}
}
genes
}
#[inline]
pub fn insert_chromosome(&mut self, chromo_name: &str, chromo: Chromosome) {
self.chromosomes.insert(chromo_name.to_string(), chromo);
}
#[inline]
pub fn insert_chromosomes(&mut self, chromos: Vec<(&str, Chromosome)>) {
for chromo in chromos {
self.insert_chromosome(chromo.0, chromo.1);
}
}
#[inline]
pub fn insert_genes(&mut self, genes: Vec<(&str, &str, Gene)>) {
for gene in genes {
if !self.chromosomes.contains_key(gene.0) {
self.insert_chromosome(&gene.0, Chromosome::new());
}
self.chromosomes.get_mut(gene.0).unwrap().insert_gene(&gene.1, gene.2);
}
}
#[inline]
pub fn set_chromosome(&mut self, chromo_name: &str, chromo: Chromosome) -> Result<(), &str> {
*self.chromosomes.get_mut(chromo_name).ok_or("No chromosome by that name exists")? = chromo;
Ok(())
}
#[inline]
pub fn set_gene(&mut self, chromo_name: &str, gene_name: &str, gene: Gene) -> Result<(), &str> {
self.chromosomes.get_mut(chromo_name).ok_or("No chromosome by that name exists")?.set_gene(gene_name, gene)
}
}
impl Display for Genome {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut display_obj: HashMap<String, HashMap<String, f32>> = HashMap::new();
for chromo in &self.chromosomes {
display_obj.insert(chromo.0.to_string(), HashMap::new());
for gene in chromo.1.genes() {
display_obj.get_mut(chromo.0).unwrap().insert(gene.0.to_string(), gene.1.value());
}
}
write!(f, "{:#?}", display_obj)
}
}