diff --git a/noodles-bcf/src/record/codec/decoder/genotypes/key.rs b/noodles-bcf/src/record/codec/decoder/genotypes/key.rs index 9b28f9a47..4326add68 100644 --- a/noodles-bcf/src/record/codec/decoder/genotypes/key.rs +++ b/noodles-bcf/src/record/codec/decoder/genotypes/key.rs @@ -3,7 +3,8 @@ use std::{error, fmt}; use noodles_vcf::{self as vcf, record::genotypes::keys::Key}; use crate::{ - header::string_maps::StringStringMap, record::codec::decoder::string_map::read_string_map_index, + header::string_maps::StringStringMap, + record::codec::decoder::string_map::{self, read_string_map_entry}, }; pub(super) fn read_key<'h>( @@ -11,33 +12,27 @@ pub(super) fn read_key<'h>( formats: &'h vcf::header::Formats, string_map: &StringStringMap, ) -> Result<&'h Key, DecodeError> { - read_string_map_index(src) - .map_err(DecodeError::InvalidStringMapIndex) - .and_then(|j| { - string_map - .get_index(j) - .ok_or(DecodeError::MissingStringMapEntry) - }) + read_string_map_entry(src, string_map) + .map_err(DecodeError::InvalidStringMap) .and_then(|raw_key| { formats .get_key_value(raw_key) .map(|(k, _)| k) - .ok_or(DecodeError::MissingFormatMapEntry) + .ok_or(DecodeError::MissingKey) }) } #[derive(Debug, Eq, PartialEq)] pub enum DecodeError { - InvalidStringMapIndex(crate::record::codec::decoder::string_map::DecodeError), - MissingStringMapEntry, - MissingFormatMapEntry, + InvalidStringMap(string_map::DecodeError), + MissingKey, } impl error::Error for DecodeError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { - Self::InvalidStringMapIndex(e) => Some(e), - _ => None, + Self::InvalidStringMap(e) => Some(e), + Self::MissingKey => None, } } } @@ -45,9 +40,8 @@ impl error::Error for DecodeError { impl fmt::Display for DecodeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::InvalidStringMapIndex(_) => write!(f, "invalid string map index"), - Self::MissingStringMapEntry => write!(f, "missing string map entry"), - Self::MissingFormatMapEntry => write!(f, "missing format map entry"), + Self::InvalidStringMap(_) => write!(f, "invalid string map"), + Self::MissingKey => write!(f, "missing key"), } } } diff --git a/noodles-bcf/src/record/codec/decoder/info/field.rs b/noodles-bcf/src/record/codec/decoder/info/field.rs index b96f32e9b..be37da024 100644 --- a/noodles-bcf/src/record/codec/decoder/info/field.rs +++ b/noodles-bcf/src/record/codec/decoder/info/field.rs @@ -1,12 +1,14 @@ -mod key; mod value; use std::{error, fmt}; use noodles_vcf as vcf; -use self::{key::read_key, value::read_value}; -use crate::header::string_maps::StringStringMap; +use self::value::read_value; +use crate::{ + header::string_maps::StringStringMap, + record::codec::decoder::string_map::{self, read_string_map_entry}, +}; pub(crate) fn read_field( src: &mut &[u8], @@ -19,7 +21,7 @@ pub(crate) fn read_field( ), DecodeError, > { - let raw_key = read_key(src, string_map).map_err(DecodeError::InvalidKey)?; + let raw_key = read_string_map_entry(src, string_map).map_err(DecodeError::InvalidStringMap)?; let (key, info) = infos .get_key_value(raw_key) @@ -32,7 +34,7 @@ pub(crate) fn read_field( #[derive(Debug, Eq, PartialEq)] pub enum DecodeError { - InvalidKey(key::DecodeError), + InvalidStringMap(string_map::DecodeError), MissingInfoMapEntry, InvalidValue(value::DecodeError), } @@ -40,7 +42,7 @@ pub enum DecodeError { impl error::Error for DecodeError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { - Self::InvalidKey(e) => Some(e), + Self::InvalidStringMap(e) => Some(e), Self::MissingInfoMapEntry => None, Self::InvalidValue(e) => Some(e), } @@ -50,7 +52,7 @@ impl error::Error for DecodeError { impl fmt::Display for DecodeError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::InvalidKey(_) => write!(f, "invalid key"), + Self::InvalidStringMap(_) => write!(f, "invalid string map"), Self::MissingInfoMapEntry => write!(f, "missing info map entry"), Self::InvalidValue(_) => write!(f, "invalid value"), } diff --git a/noodles-bcf/src/record/codec/decoder/info/field/key.rs b/noodles-bcf/src/record/codec/decoder/info/field/key.rs deleted file mode 100644 index f0cab282b..000000000 --- a/noodles-bcf/src/record/codec/decoder/info/field/key.rs +++ /dev/null @@ -1,59 +0,0 @@ -use std::{error, fmt}; - -use crate::{ - header::string_maps::StringStringMap, record::codec::decoder::string_map::read_string_map_index, -}; - -pub(super) fn read_key<'m>( - src: &mut &[u8], - string_map: &'m StringStringMap, -) -> Result<&'m str, DecodeError> { - read_string_map_index(src) - .map_err(DecodeError::InvalidStringMapIndex) - .and_then(|j| { - string_map - .get_index(j) - .ok_or(DecodeError::MissingStringMapEntry) - }) -} - -#[derive(Debug, Eq, PartialEq)] -pub enum DecodeError { - InvalidStringMapIndex(crate::record::codec::decoder::string_map::DecodeError), - MissingStringMapEntry, -} - -impl error::Error for DecodeError { - fn source(&self) -> Option<&(dyn error::Error + 'static)> { - match self { - Self::InvalidStringMapIndex(e) => Some(e), - _ => None, - } - } -} - -impl fmt::Display for DecodeError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::InvalidStringMapIndex(_) => write!(f, "invalid string map index"), - Self::MissingStringMapEntry => write!(f, "missing string map entry"), - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_read_key() { - // Some(Type::Int8(Some(Int8::Value(1)))) - let mut src = &[0x11, 0x01][..]; - - let mut string_map = StringStringMap::default(); - string_map.insert("PASS".into()); - string_map.insert("NS".into()); - - assert_eq!(read_key(&mut src, &string_map), Ok("NS")); - } -} diff --git a/noodles-bcf/src/record/codec/decoder/string_map.rs b/noodles-bcf/src/record/codec/decoder/string_map.rs index 9314ab0e2..6f4a979a3 100644 --- a/noodles-bcf/src/record/codec/decoder/string_map.rs +++ b/noodles-bcf/src/record/codec/decoder/string_map.rs @@ -1,8 +1,11 @@ use std::{error, fmt, num}; -use crate::lazy::record::{ - value::{Array, Int16, Int32, Int8}, - Value, +use crate::{ + header::string_maps::StringMap, + lazy::record::{ + value::{Array, Int16, Int32, Int8}, + Value, + }, }; use super::value::read_value; @@ -36,12 +39,21 @@ pub fn read_string_map_indices(src: &mut &[u8]) -> Result, DecodeErro .collect() } +pub fn read_string_map_entry<'m>( + src: &mut &[u8], + string_map: &'m StringMap, +) -> Result<&'m str, DecodeError> { + read_string_map_index(src) + .and_then(|j| string_map.get_index(j).ok_or(DecodeError::MissingEntry)) +} + #[allow(clippy::enum_variant_names)] #[derive(Debug, Eq, PartialEq)] pub enum DecodeError { InvalidValue(super::value::DecodeError), InvalidIndex(num::TryFromIntError), InvalidIndexValue, + MissingEntry, } impl error::Error for DecodeError { @@ -49,7 +61,7 @@ impl error::Error for DecodeError { match self { Self::InvalidValue(e) => Some(e), Self::InvalidIndex(e) => Some(e), - Self::InvalidIndexValue => None, + _ => None, } } } @@ -60,6 +72,7 @@ impl fmt::Display for DecodeError { Self::InvalidValue(_) => write!(f, "invalid value"), Self::InvalidIndex(_) => write!(f, "invalid index"), Self::InvalidIndexValue => write!(f, "invalid index value"), + Self::MissingEntry => write!(f, "missing entry"), } } } @@ -160,4 +173,23 @@ mod tests { Err(DecodeError::InvalidIndexValue) ); } + + #[test] + fn test_read_string_map_entry() { + let mut string_map = StringMap::default(); + string_map.insert(String::from("PASS")); + string_map.insert(String::from("NS")); + string_map.insert(String::from("DP")); + + // Some(Type::Int8(Some(Int8::Value(1)))) + let mut src = &[0x11, 0x01][..]; + assert_eq!(read_string_map_entry(&mut src, &string_map), Ok("NS")); + + // Some(Type::Int8(Some(Int8::Value(8)))) + let mut src = &[0x11, 0x08][..]; + assert_eq!( + read_string_map_entry(&mut src, &string_map), + Err(DecodeError::MissingEntry) + ); + } }