pub fn parse_hgvs(input: &str) -> Result<HgvsVariant, ParseHgvsError>Expand description
Parses an HGVS string into the Rust HgvsVariant model.
Leading and trailing whitespace are ignored before parsing.
The returned model keeps the HGVS expression split into:
reference: the reference source for a variant.coordinate_system: the one-letter reference coordinate type.description, the nucleotide or protein variant description.
ยงExamples
A splice-adjacent substitution in an intron:
use tinyhgvs::{NucleotideAnchor, NucleotideEdit, VariantDescription, parse_hgvs};
let variant = parse_hgvs(" NM_004006.2:c.357+1G>A ").unwrap();
match variant.description {
VariantDescription::Nucleotide(nucleotide) => {
assert_eq!(nucleotide.location.start().unwrap().anchor().unwrap(), NucleotideAnchor::Absolute);
assert_eq!(nucleotide.location.start().unwrap().coordinate().unwrap(), 357);
assert_eq!(nucleotide.location.start().unwrap().offset().unwrap(), 1);
assert!(matches!(
nucleotide.edit,
NucleotideEdit::Substitution { ref reference, ref alternate }
if reference == "G" && alternate == "A"
));
}
_ => unreachable!("expected nucleotide variant"),
}A 5โ UTR substitution keeps the signed coordinate from the HGVS string:
use tinyhgvs::{NucleotideAnchor, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NM_007373.4:c.-1C>T").unwrap();
match variant.description {
VariantDescription::Nucleotide(nucleotide) => {
assert_eq!(nucleotide.location.start().unwrap().anchor().unwrap(), NucleotideAnchor::RelativeCdsStart);
assert_eq!(nucleotide.location.start().unwrap().coordinate().unwrap(), -1);
assert_eq!(nucleotide.location.start().unwrap().offset().unwrap(), 0);
}
_ => unreachable!("expected nucleotide variant"),
}CDS-anchored intronic positions in the 5โ and 3โ UTR:
use tinyhgvs::{NucleotideAnchor, VariantDescription, parse_hgvs};
let five_prime_intronic = parse_hgvs("NM_001385026.1:c.-106+2T>A").unwrap();
let three_prime_intronic = parse_hgvs("NM_001272071.2:c.*639-1G>A").unwrap();
match five_prime_intronic.description {
VariantDescription::Nucleotide(nucleotide) => {
assert_eq!(nucleotide.location.start().unwrap().anchor().unwrap(), NucleotideAnchor::RelativeCdsStart);
assert_eq!(nucleotide.location.start().unwrap().coordinate().unwrap(), -106);
assert_eq!(nucleotide.location.start().unwrap().offset().unwrap(), 2);
}
_ => unreachable!("expected nucleotide variant"),
}
match three_prime_intronic.description {
VariantDescription::Nucleotide(nucleotide) => {
assert_eq!(nucleotide.location.start().unwrap().anchor().unwrap(), NucleotideAnchor::RelativeCdsEnd);
assert_eq!(nucleotide.location.start().unwrap().coordinate().unwrap(), 639);
assert_eq!(nucleotide.location.start().unwrap().offset().unwrap(), -1);
}
_ => unreachable!("expected nucleotide variant"),
}A nonsense mutation leading to an early termination consequence at protein-level:
use tinyhgvs::{ProteinEffect, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NP_003997.1:p.Trp24Ter").unwrap();
match variant.description {
VariantDescription::Protein(protein) => {
assert!(!protein.is_predicted);
assert!(matches!(protein.effect, ProteinEffect::Edit { .. }));
}
_ => unreachable!("expected protein variant"),
}A repeated sequence is returned as a repeat edit:
use tinyhgvs::{NucleotideEdit, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NM_004006.3:r.-124_-123[14]").unwrap();
match variant.description {
VariantDescription::Nucleotide(nucleotide) => {
let NucleotideEdit::Repeat { blocks } = nucleotide.edit else {
unreachable!("expected repeat edit");
};
assert_eq!(blocks[0].count, 14);
assert_eq!(blocks[0].unit, None);
}
_ => unreachable!("expected nucleotide variant"),
}A nucleotide allele variant with two in-trans alleles:
use tinyhgvs::{AllelePhase, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NM_004006.2:c.[2376G>C];[2376=]").unwrap();
match variant.description {
VariantDescription::NucleotideAllele(allele) => {
assert_eq!(allele.allele_one.variants.len(), 1);
assert!(allele.allele_two.is_some());
assert_eq!(allele.phase, Some(AllelePhase::Trans));
}
_ => unreachable!("expected nucleotide allele"),
}A protein frameshift can be parsed in either short or long form:
use tinyhgvs::{ProteinEdit, ProteinEffect, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NP_0123456.1:p.Arg97ProfsTer23").unwrap();
match variant.description {
VariantDescription::Protein(protein) => match protein.effect {
ProteinEffect::Edit { edit: ProteinEdit::Frameshift { to_residue, stop }, .. } => {
assert_eq!(to_residue.as_deref(), Some("Pro"));
assert_eq!(stop.ordinal, Some(23));
}
_ => unreachable!("expected protein frameshift"),
},
_ => unreachable!("expected protein variant"),
}A protein extension keeps the extended terminus, the first new residue when present, and the new terminal ordinal together:
use tinyhgvs::{ProteinEdit, ProteinEffect, VariantDescription, parse_hgvs};
let variant = parse_hgvs("NP_003997.2:p.Ter110GlnextTer17").unwrap();
match variant.description {
VariantDescription::Protein(protein) => match protein.effect {
ProteinEffect::Edit { edit: ProteinEdit::Extension(extension), .. } => {
assert_eq!(extension.to_residue.as_deref(), Some("Gln"));
assert_eq!(extension.terminal_ordinal, Some(17));
}
_ => unreachable!("expected protein extension"),
},
_ => unreachable!("expected protein variant"),
}Unsupported syntax is reported as a structured crate::ParseHgvsError:
use tinyhgvs::parse_hgvs;
let error = parse_hgvs("NM_004006.3:r.spl").unwrap_err();
assert_eq!(error.code(), "unsupported.rna_special_state");