use anyhow::Result;
use std::fmt::{self, Display};
use tabled::{
settings::{
object::{Columns, Rows},
Disable, Modify, Panel, Width,
},
Table, Tabled,
};
use crate::build::{get_database_path, TelomereRepeatRow};
#[derive(Debug, Clone)]
pub struct Seq(pub Vec<String>);
impl Seq {
pub fn new() -> Self {
Self(vec![])
}
pub fn push(&mut self, seq: String) {
self.0.push(seq);
}
pub fn get(&self, index: usize) -> Option<&String> {
self.0.get(index)
}
pub fn get_inner(&self) -> &Vec<String> {
&self.0
}
}
impl Display for Seq {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.0.join(", ");
write!(f, "{}", inner)
}
}
#[derive(Debug, Clone, Tabled)]
pub struct TelomereSeq {
#[tabled(rename = "Clade")]
pub clade: String,
#[tabled(rename = "Telomeric repeat units")]
pub seq: Seq,
pub length: usize,
}
impl TelomereSeq {
pub fn new(clade: String, seq: Seq) -> Self {
Self {
clade,
seq,
length: 0,
}
}
pub fn push(&mut self, seq: String) {
if !self.seq.0.contains(&seq) {
self.seq.push(seq);
}
}
pub fn set_clade(&mut self, clade: String) {
self.clade = clade;
}
pub fn set_length(&mut self) {
self.length = self.seq.0.len();
}
}
pub fn get_clades() -> Result<Vec<String>> {
let path = get_database_path()?;
let mut rdr = csv::Reader::from_path(path)?;
let mut out = vec![];
for result in rdr.deserialize() {
let record: TelomereRepeatRow = result?;
let order = record.order;
out.push(order);
}
out.dedup();
out.retain(|e| e != "");
Ok(out)
}
pub fn return_telomere_sequence(clade: String) -> Result<TelomereSeq> {
let path = get_database_path()?;
let mut rdr = csv::Reader::from_path(path)?;
let mut telomere_seq = TelomereSeq::new(clade.clone(), Seq::new());
for result in rdr.deserialize() {
let record: TelomereRepeatRow = result?;
if record.order == clade {
telomere_seq.push(record.telomeric_repeat);
}
}
telomere_seq.set_length();
Ok(telomere_seq)
}
pub fn print_table() -> Result<()> {
let mut clade_vec = Vec::new();
let clades = get_clades()?;
for clade in clades {
clade_vec.push(return_telomere_sequence(clade)?);
}
eprintln!(
"{}",
Table::new(&clade_vec)
.with(
Modify::new(Rows::new(1..clade_vec.len() - 1)).with(Width::wrap(30).keep_words(true))
)
.with(Disable::column(Columns::new(2..3)))
.with(Panel::footer(
"This table is created from a curated database of repeats. This database can be found in its raw form here: https://github.com/tolkit/telomeric-identifier/tree/main/clades/curated.csv"
)).with(Width::wrap(60).keep_words(true))
);
Ok(())
}