fast-nnt 0.4.0

Rust implementation of the NeighborNet phylogenetic network algorithm.
Documentation
pub mod active_set_weights;
pub mod band;
pub mod cg_weights;
pub mod cgnr;
pub mod nnls_ops;

pub use cg_weights::CGSolveStats;

use clap::ValueEnum;

#[derive(Clone, Copy, Debug, PartialEq, Eq, ValueEnum, Default)]
#[clap(rename_all = "kebab-case")]
pub enum InferenceMethod {
    #[default]
    #[clap(alias = "activeset", alias = "active_set")]
    ActiveSet,
    #[clap(
        alias = "splitstree4",
        alias = "splits-tree4",
        alias = "splits_tree4",
        alias = "conjugate-gradient",
        alias = "conjugate_gradient"
    )]
    CG,
}

impl InferenceMethod {
    pub fn as_str(&self) -> &'static str {
        match self {
            InferenceMethod::ActiveSet => "active-set",
            InferenceMethod::CG => "cg",
        }
    }

    pub fn from_option(opt: Option<&str>) -> anyhow::Result<Self> {
        opt.map_or(Ok(InferenceMethod::default()), str::parse)
    }
}

impl std::str::FromStr for InferenceMethod {
    type Err = anyhow::Error;

    fn from_str(s: &str) -> anyhow::Result<Self> {
        let normalized: String = s.to_lowercase().replace(['-', '_'], "");
        match normalized.as_str() {
            "activeset" => Ok(InferenceMethod::ActiveSet),
            "cg" | "conjugategradient" | "splitstree4" => Ok(InferenceMethod::CG),
            _ => anyhow::bail!(
                "unknown inference method '{}' (expected 'active-set' or 'cg')",
                s
            ),
        }
    }
}