noodles_bam/record/codec/decoder/data/field/value/array/
subtype.rs1use std::{error, fmt};
2
3use noodles_sam::alignment::record::data::field::value::array::Subtype;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
7pub enum DecodeError {
8 UnexpectedEof,
10 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}