use clap::Parser;
use rsomics_bed_validate::validate;
use rsomics_common::{CommonFlags, Result, RsomicsError, Tool, ToolMeta};
use rsomics_help::{Example, FlagSpec, HelpSpec, Section};
use std::fs::File;
use std::io::{self, BufReader};
use std::path::PathBuf;
pub const META: ToolMeta = ToolMeta {
name: env!("CARGO_PKG_NAME"),
version: env!("CARGO_PKG_VERSION"),
};
pub const HELP: HelpSpec = HelpSpec {
name: META.name,
version: META.version,
tagline: "Validate BED file format: check field counts, coordinate ordering, and integer parsing.",
origin: None,
usage_lines: &["[OPTIONS] [INPUT]"],
sections: &[Section {
title: "OPTIONS",
flags: &[
FlagSpec {
short: None,
long: "strict",
aliases: &[],
value: None,
type_hint: Some("bool"),
required: false,
default: Some("false"),
description: "Exit with non-zero status if any errors are found",
why_default: None,
},
FlagSpec {
short: Some('h'),
long: "help",
aliases: &[],
value: None,
type_hint: Some("bool"),
required: false,
default: None,
description: "Show this help",
why_default: None,
},
],
}],
examples: &[
Example {
description: "Validate a BED file",
command: "rsomics-bed-validate intervals.bed",
},
Example {
description: "Fail with non-zero exit if invalid",
command: "rsomics-bed-validate --strict intervals.bed",
},
],
json_result_schema_doc: None,
};
#[derive(Parser, Debug)]
#[command(name = "rsomics-bed-validate", disable_help_flag = true)]
pub struct Cli {
pub input: Option<PathBuf>,
#[arg(long)]
pub strict: bool,
#[command(flatten)]
pub common: CommonFlags,
}
impl Tool for Cli {
fn meta() -> ToolMeta {
META
}
fn common(&self) -> &CommonFlags {
&self.common
}
fn execute(self) -> Result<()> {
let result = match &self.input {
Some(p) => {
let reader = BufReader::new(File::open(p).map_err(RsomicsError::Io)?);
validate(reader)?
}
None => {
let stdin = io::stdin();
validate(stdin.lock())?
}
};
if result.is_valid {
println!("OK: {} records, no errors", result.records);
} else {
for e in &result.errors {
eprintln!("ERROR: {e}");
}
println!(
"INVALID: {} records, {} errors",
result.records,
result.errors.len()
);
if self.strict {
return Err(rsomics_common::RsomicsError::InvalidInput(
"BED validation failed".into(),
));
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use clap::CommandFactory;
#[test]
fn cli_definition_is_valid() {
super::Cli::command().debug_assert();
}
}