mod display;
mod ds;
mod error;
mod impl_parse;
mod impl_validate;
mod parse_funcs;
use std::str::FromStr;
pub use crate::parser::display::*;
pub use crate::parser::ds::*;
pub use crate::parser::error::*;
use crate::parser::impl_parse::*;
impl FromStr for HgvsVariant {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
.map_err(|_e| Error::InvalidHgvsVariant(s.to_string()))
.map(|(_rest, variant)| variant)
}
}
impl FromStr for GenomeInterval {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
.map_err(|_e| Error::InvalidGenomeInterval(s.to_string()))
.map(|(_rest, g_interval)| g_interval)
}
}
impl FromStr for TxInterval {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
.map_err(|_e| Error::InvalidTxInterval(s.to_string()))
.map(|(_rest, g_interval)| g_interval)
}
}
impl FromStr for CdsInterval {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s)
.map_err(|_e| Error::InvalidCdsInterval(s.to_string()))
.map(|(_rest, g_interval)| g_interval)
}
}
#[cfg(test)]
mod test {
use anyhow::Error;
use std::{
fs::File,
io::{BufRead, BufReader},
str::FromStr,
};
use crate::parser::{
Accession, CdsFrom, CdsInterval, CdsLocEdit, CdsPos, GenomeInterval, Mu, NaEdit,
};
use super::HgvsVariant;
#[test]
fn from_str_basic() -> Result<(), Error> {
assert_eq!(
HgvsVariant::from_str("NM_01234.5:c.22+1A>T")?,
HgvsVariant::CdsVariant {
accession: Accession {
value: "NM_01234.5".to_string()
},
gene_symbol: None,
loc_edit: CdsLocEdit {
loc: Mu::Certain(CdsInterval {
start: CdsPos {
base: 22,
offset: Some(1),
cds_from: CdsFrom::Start
},
end: CdsPos {
base: 22,
offset: Some(1),
cds_from: CdsFrom::Start
}
}),
edit: Mu::Certain(NaEdit::RefAlt {
reference: "A".to_string(),
alternative: "T".to_string()
})
}
}
);
Ok(())
}
#[test]
fn not_ok() -> Result<(), Error> {
assert!(HgvsVariant::from_str("x").is_err());
Ok(())
}
#[test]
fn hgvs_gauntlet() -> Result<(), Error> {
let reader = BufReader::new(File::open("tests/data/parser/gauntlet")?);
for line in reader.lines() {
let line = line?;
let line = line.trim();
if !line.starts_with('#') && !line.is_empty() {
let result = HgvsVariant::from_str(line);
assert!(result.is_ok(), "line = {}; result = {:?}", &line, &result);
}
}
Ok(())
}
#[test]
fn hgvs_reject() -> Result<(), Error> {
let reader = BufReader::new(File::open("tests/data/parser/reject")?);
for line in reader.lines() {
let line = line?;
let line = line.trim();
if !line.starts_with('#') && !line.is_empty() {
assert!(HgvsVariant::from_str(line).is_err(), "line = {line}")
}
}
Ok(())
}
#[test]
fn genome_interval_from_str() -> Result<(), Error> {
assert!(GenomeInterval::from_str("x").is_err());
assert_eq!(
GenomeInterval::from_str("1")?,
GenomeInterval {
start: Some(1),
end: Some(1)
}
);
assert_eq!(
GenomeInterval::from_str("1_1")?,
GenomeInterval {
start: Some(1),
end: Some(1)
}
);
assert_eq!(
GenomeInterval::from_str("?_1")?,
GenomeInterval {
start: None,
end: Some(1)
}
);
assert_eq!(
GenomeInterval::from_str("1_?")?,
GenomeInterval {
start: Some(1),
end: None
}
);
assert_eq!(
GenomeInterval::from_str("?_?")?,
GenomeInterval {
start: None,
end: None
}
);
Ok(())
}
}