use clap_derive::{Parser, Subcommand, ValueEnum};
use serde::{Deserialize, Deserializer};
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Parser, Debug)]
#[clap(version, about)]
pub(crate) struct Predictosaurus {
#[clap(subcommand)]
pub(crate) command: Command,
}
#[derive(Subcommand, Debug)]
pub(crate) enum Command {
Build {
#[clap(short, long)]
calls: PathBuf,
#[clap(short, long)]
observations: Vec<ObservationFile>,
#[clap(short, long, default_value = "0.8")]
min_prob_present: f32,
#[clap(long)]
output: PathBuf,
},
Process {
#[clap(short, long)]
features: PathBuf,
#[clap(short, long)]
reference: PathBuf,
#[clap(short, long)]
graph: PathBuf,
#[clap(short, long)]
output: PathBuf,
},
Plot {
#[clap(short, long)]
input: PathBuf,
#[clap(short, long)]
format: Format,
#[clap(short, long)]
output: PathBuf,
},
}
#[derive(Debug, Clone, ValueEnum)]
pub(crate) enum Format {
Html,
Tsv,
Vega,
}
#[derive(Debug, Clone)]
pub(crate) struct ObservationFile {
pub(crate) path: PathBuf,
pub(crate) sample: String,
}
impl FromStr for ObservationFile {
type Err = String;
fn from_str(string: &str) -> Result<ObservationFile, Self::Err> {
let (sample, path) = string.split_once('=').expect("Invalid observation file parameter format. Make sure to use the format `--observations sample=observations.vcf`");
Ok(ObservationFile {
sample: sample.to_string(),
path: PathBuf::from(path),
})
}
}
impl<'de> Deserialize<'de> for ObservationFile {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let string = String::deserialize(deserializer)?;
Ok(ObservationFile::from_str(&string).unwrap())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_str_parses_valid_observation_file() {
let input = "sample1=observations.vcf";
let observation_file = ObservationFile::from_str(input).unwrap();
assert_eq!(observation_file.sample, "sample1");
assert_eq!(observation_file.path, PathBuf::from("observations.vcf"));
}
#[test]
#[should_panic]
fn from_str_fails_on_invalid_format() {
let input = "invalid_format";
let result = ObservationFile::from_str(input);
}
}