noodles_bam/record/codec/decoder/data/field/value/array/
subtype.rs

1use std::{error, fmt};
2
3use noodles_sam::alignment::record::data::field::value::array::Subtype;
4
5/// An error when a raw BAM record data field value subtype fails to parse.
6#[derive(Clone, Debug, Eq, PartialEq)]
7pub enum DecodeError {
8    /// Unexpected EOF.
9    UnexpectedEof,
10    /// The subtype is invalid.
11    Invalid { actual: u8 },
12}
13
14impl error::Error for DecodeError {}
15
16impl fmt::Display for DecodeError {
17    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18        match self {
19            Self::UnexpectedEof => write!(f, "unexpected EOF"),
20            Self::Invalid { actual } => write!(
21                f,
22                "invalid input: expected {{c, C, s, S, i, I, f}}, got {}",
23                char::from(*actual)
24            ),
25        }
26    }
27}
28
29pub fn read_subtype(src: &mut &[u8]) -> Result<Subtype, DecodeError> {
30    let (n, rest) = src.split_first().ok_or(DecodeError::UnexpectedEof)?;
31
32    *src = rest;
33
34    match *n {
35        b'c' => Ok(Subtype::Int8),
36        b'C' => Ok(Subtype::UInt8),
37        b's' => Ok(Subtype::Int16),
38        b'S' => Ok(Subtype::UInt16),
39        b'i' => Ok(Subtype::Int32),
40        b'I' => Ok(Subtype::UInt32),
41        b'f' => Ok(Subtype::Float),
42        _ => Err(DecodeError::Invalid { actual: *n }),
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_read_subtype() -> Result<(), DecodeError> {
52        fn t(mut src: &[u8], expected: Subtype) -> Result<(), DecodeError> {
53            assert_eq!(read_subtype(&mut src)?, expected);
54            Ok(())
55        }
56
57        t(b"c", Subtype::Int8)?;
58        t(b"C", Subtype::UInt8)?;
59        t(b"s", Subtype::Int16)?;
60        t(b"S", Subtype::UInt16)?;
61        t(b"i", Subtype::Int32)?;
62        t(b"I", Subtype::UInt32)?;
63        t(b"f", Subtype::Float)?;
64
65        let data = b"";
66        let mut src = &data[..];
67        assert_eq!(read_subtype(&mut src), Err(DecodeError::UnexpectedEof));
68
69        let data = b"n";
70        let mut src = &data[..];
71        assert_eq!(
72            read_subtype(&mut src),
73            Err(DecodeError::Invalid { actual: b'n' })
74        );
75
76        Ok(())
77    }
78}