use std::{convert::TryFrom, mem};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
use crate::ReadStructureError;
#[non_exhaustive]
#[derive(Debug, Copy, Clone, EnumIter, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[repr(u8)]
pub enum SegmentType {
Template = b'T',
SampleBarcode = b'B',
MolecularBarcode = b'M',
Skip = b'S',
CellularBarcode = b'C',
}
impl SegmentType {
pub fn value(&self) -> char {
let value = *self as u8;
value as char
}
}
impl TryFrom<char> for SegmentType {
type Error = ReadStructureError;
fn try_from(value: char) -> Result<Self, Self::Error> {
match value {
'T' => Ok(SegmentType::Template),
'B' => Ok(SegmentType::SampleBarcode),
'M' => Ok(SegmentType::MolecularBarcode),
'S' => Ok(SegmentType::Skip),
'C' => Ok(SegmentType::CellularBarcode),
_ => Err(ReadStructureError::ReadSegmentTypeInvalid(value)),
}
}
}
impl TryFrom<u8> for SegmentType {
type Error = ReadStructureError;
fn try_from(value: u8) -> Result<Self, Self::Error> {
Self::try_from(value as char)
}
}
#[cfg(test)]
mod test {
use std::convert::TryFrom;
use crate::{segment_type::SegmentType, ReadStructureError};
use strum::IntoEnumIterator;
#[test]
fn test_segment_type_round_trip() -> Result<(), ReadStructureError> {
assert_eq!(SegmentType::iter().len(), 5);
for tpe in SegmentType::iter() {
assert_eq!(SegmentType::try_from(tpe.value())?, tpe);
}
Ok(())
}
#[test]
fn test_invalid_segment_type() {
assert!(SegmentType::try_from(b'G').is_err());
}
}