noodles_sam/alignment/record/data/field/
value.rs

1//! Alignment record data field value.
2
3pub mod array;
4
5use std::io;
6
7use bstr::BStr;
8
9pub use self::array::Array;
10use super::Type;
11
12/// An alignment record data field value.
13#[derive(Debug)]
14pub enum Value<'a> {
15    /// A character (`A`).
16    Character(u8),
17    /// An 8-bit integer (`c`).
18    Int8(i8),
19    /// An 8-bit unsigned integer (`C`).
20    UInt8(u8),
21    /// A 16-bit integer (`s`).
22    Int16(i16),
23    /// A 16-bit unsigned integer (`S`).
24    UInt16(u16),
25    /// A 32-bit integer (`i`).
26    Int32(i32),
27    /// A 32-bit unsigned integer (`I`).
28    UInt32(u32),
29    /// A single-precision floating-point (`f`).
30    Float(f32),
31    /// A string (`Z`).
32    String(&'a BStr),
33    /// A hex string (`H`).
34    Hex(&'a BStr),
35    /// An array (`B`).
36    Array(Array<'a>),
37}
38
39impl Value<'_> {
40    /// Return the type of the value.
41    ///
42    /// # Examples
43    ///
44    /// ```
45    /// use noodles_sam::alignment::record::data::field::{Type, Value};
46    /// assert_eq!(Value::UInt8(0).ty(), Type::UInt8);
47    /// ```
48    pub fn ty(&self) -> Type {
49        match self {
50            Self::Character(_) => Type::Character,
51            Self::Int8(_) => Type::Int8,
52            Self::UInt8(_) => Type::UInt8,
53            Self::Int16(_) => Type::Int16,
54            Self::UInt16(_) => Type::UInt16,
55            Self::Int32(_) => Type::Int32,
56            Self::UInt32(_) => Type::UInt32,
57            Self::Float(_) => Type::Float,
58            Self::String(_) => Type::String,
59            Self::Hex(_) => Type::Hex,
60            Self::Array(_) => Type::Array,
61        }
62    }
63
64    /// Returns the value as a 64-bit integer.
65    ///
66    /// This is a convenience method that converts any integer to an `i64`, which captures the
67    /// entire range of all record data field integer values.
68    ///
69    /// # Examples
70    ///
71    /// ```
72    /// use noodles_sam::alignment::record::data::field::Value;
73    /// assert_eq!(Value::Int8(8).as_int(), Some(8));
74    /// assert_eq!(Value::UInt32(13).as_int(), Some(13));
75    /// assert!(Value::Float(0.0).as_int().is_none());
76    /// ```
77    pub fn as_int(&self) -> Option<i64> {
78        match self {
79            Self::Int8(n) => Some(i64::from(*n)),
80            Self::UInt8(n) => Some(i64::from(*n)),
81            Self::Int16(n) => Some(i64::from(*n)),
82            Self::UInt16(n) => Some(i64::from(*n)),
83            Self::Int32(n) => Some(i64::from(*n)),
84            Self::UInt32(n) => Some(i64::from(*n)),
85            _ => None,
86        }
87    }
88}
89
90impl<'a> TryFrom<Value<'a>> for crate::alignment::record_buf::data::field::Value {
91    type Error = io::Error;
92
93    fn try_from(value: Value<'a>) -> Result<Self, Self::Error> {
94        match value {
95            Value::Character(b) => Ok(Self::Character(b)),
96            Value::Int8(n) => Ok(Self::Int8(n)),
97            Value::UInt8(n) => Ok(Self::UInt8(n)),
98            Value::Int16(n) => Ok(Self::Int16(n)),
99            Value::UInt16(n) => Ok(Self::UInt16(n)),
100            Value::Int32(n) => Ok(Self::Int32(n)),
101            Value::UInt32(n) => Ok(Self::UInt32(n)),
102            Value::Float(n) => Ok(Self::Float(n)),
103            Value::String(s) => Ok(Self::String(s.into())),
104            Value::Hex(s) => Ok(Self::Hex(s.into())),
105            Value::Array(array) => array.try_into().map(Self::Array),
106        }
107    }
108}