segul 0.23.2

An ultrafast and memory-efficient tool for phylogenomics
Documentation
//! Handler for summarizing contig files
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel;

use colored::Colorize;
use rayon::prelude::*;

use crate::writer::contigs::ContigSummaryWriter;
use crate::{
    helper::{types::ContigFmt, utils::set_spinner},
    stats::contigs::ContigSummary,
};

pub struct ContigSummaryHandler<'a> {
    /// Contig files
    files: &'a [PathBuf],
    /// Contig sequence format
    input_fmt: &'a ContigFmt,
    /// Output path
    output: &'a Path,
    /// Output file prefix
    prefix: Option<&'a str>,
}

impl<'a> ContigSummaryHandler<'a> {
    pub fn new(
        files: &'a [PathBuf],
        input_fmt: &'a ContigFmt,
        output: &'a Path,
        prefix: Option<&'a str>,
    ) -> Self {
        Self {
            files,
            input_fmt,
            output,
            prefix,
        }
    }

    pub fn summarize(&self) {
        let spin = set_spinner();
        spin.set_message("Calculating summary of contig files");
        let contig_summary = self.summarize_contigs();
        let writer = ContigSummaryWriter::new(&contig_summary, self.output, self.prefix);
        spin.set_message("Writing records\n");
        writer.write().expect("Failed writing to file");
        spin.finish_with_message("Finished processing contig files\n");
        self.print_input_info();
    }

    fn summarize_contigs(&self) -> Vec<ContigSummary> {
        if self.files.is_empty() {
            panic!("No contig files found")
        }

        if self.files.len() == 1 {
            return vec![self.process_contigs(&self.files[0])];
        }

        let (sender, receiver) = channel();

        self.files.par_iter().for_each_with(sender, |s, p| {
            let summary = self.process_contigs(p);
            s.send(summary).expect("Failed sending data");
        });

        receiver.iter().collect()
    }

    fn process_contigs(&self, input: &Path) -> ContigSummary {
        let mut summary = ContigSummary::new();
        summary.summarize(input, self.input_fmt);
        summary
    }

    fn print_input_info(&self) {
        log::info!("{}", "Output".yellow());
        log::info!("{:18}: {}", "Dir", self.output.display());
    }
}