Skip to content

Commit

Permalink
vcf/header/parser/record/value/map/other: Only parse Values field in …
Browse files Browse the repository at this point in the history
…VCF 4.3+ META records
  • Loading branch information
zaeleus committed Sep 18, 2023
1 parent f40d7a3 commit 47715cd
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 5 deletions.
4 changes: 2 additions & 2 deletions noodles-vcf/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
When the input is VCF 4.2, this allows the `Child` or `Derived` field to
act as the record ID in the value collection.

* vcf/header/parser/record/value/map/other: Only parse `Values` field in META
record.
* vcf/header/parser/record/value/map/other: Only parse `Values` field in VCF
4.3+ META records.

[#201]: https://github.com/zaeleus/noodles/issues/201
[#203]: https://github.com/zaeleus/noodles/issues/203
Expand Down
2 changes: 1 addition & 1 deletion noodles-vcf/src/header/parser/record/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ pub(super) fn parse_value(
.map_err(ParseError::InvalidContig),
Key::Other(k) => {
let v = if k.as_ref() == META {
map::other::parse_meta(src)
map::other::parse_meta(src, file_format)
.map(Value::from)
.map_err(|e| ParseError::InvalidOtherMap(k.clone(), e))?
} else if k.as_ref() == PEDIGREE {
Expand Down
36 changes: 34 additions & 2 deletions noodles-vcf/src/header/parser/record/value/map/other.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,12 @@ pub fn parse_other(src: &mut &[u8]) -> Result<(String, Map<Other>), ParseError>
))
}

pub fn parse_meta(src: &mut &[u8]) -> Result<(String, Map<Other>), ParseError> {
pub fn parse_meta(
src: &mut &[u8],
file_format: FileFormat,
) -> Result<(String, Map<Other>), ParseError> {
const VALUES: &str = "Values";
const VCF_4_3: FileFormat = FileFormat::new(4, 3);

super::consume_prefix(src).map_err(|e| ParseError::new(None, ParseErrorKind::InvalidMap(e)))?;

Expand All @@ -119,7 +123,7 @@ pub fn parse_meta(src: &mut &[u8]) -> Result<(String, Map<Other>), ParseError> {
match tag {
tag::ID => parse_id(src, &id).and_then(|v| try_replace(&mut id, &None, tag::ID, v))?,
Tag::Other(t) => {
if t == VALUES {
if file_format >= VCF_4_3 && t == VALUES {
parse_values(src, &id, &t)
.and_then(|value| try_insert(&mut other_fields, &id, t, value))?;
} else {
Expand Down Expand Up @@ -302,6 +306,34 @@ mod tests {
assert_eq!(parse_other(&mut src), Ok(expected));
}

#[test]
fn test_parse_meta() -> Result<(), Box<dyn std::error::Error>> {
const VCF_4_2: FileFormat = FileFormat::new(4, 2);
const VCF_4_3: FileFormat = FileFormat::new(4, 3);

let mut src = &b"<ID=Assay,Values=[WholeGenome, Exome]>"[..];
assert_eq!(
parse_meta(&mut src, VCF_4_3),
Ok((
String::from("Assay"),
Map::<Other>::builder()
.insert("Values".parse()?, "[WholeGenome, Exome]")
.build()?
))
);

let mut src = &b"<ID=Assay,Values=[WholeGenome, Exome]>"[..];
assert!(matches!(
parse_meta(&mut src, VCF_4_2),
Err(ParseError {
id,
kind: ParseErrorKind::InvalidKey(_)
}) if id == Some(String::from("Assay"))
));

Ok(())
}

#[test]
fn test_parse_pedigree() -> Result<(), Box<dyn std::error::Error>> {
const VCF_4_2: FileFormat = FileFormat::new(4, 2);
Expand Down

0 comments on commit 47715cd

Please sign in to comment.