bed_utils/bed/
strand.rs

1//! BED record feature strand.
2
3use std::{error, fmt, str::FromStr};
4
5use bincode::{Decode, Encode};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9/// A BED record feature strand.
10#[derive(Encode, Decode, Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum Strand {
13    /// Forward (sense or coding) strand (`+`).
14    Forward,
15    /// Reverse (antisense or complementary) strand (`-`).
16    Reverse,
17}
18
19impl AsRef<str> for Strand {
20    fn as_ref(&self) -> &str {
21        match self {
22            Self::Forward => "+",
23            Self::Reverse => "-",
24        }
25    }
26}
27
28impl fmt::Display for Strand {
29    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30        f.write_str(self.as_ref())
31    }
32}
33
34/// An error returned when a raw BED record strand fails to parse.
35#[derive(Clone, Debug, Eq, PartialEq)]
36pub enum ParseError {
37    /// The input is empty.
38    Empty,
39    /// The input is invalid.
40    Invalid,
41}
42
43impl error::Error for ParseError {}
44
45impl fmt::Display for ParseError {
46    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
47        match self {
48            Self::Empty => f.write_str("empty input"),
49            Self::Invalid => f.write_str("invalid input"),
50        }
51    }
52}
53
54impl FromStr for Strand {
55    type Err = ParseError;
56
57    fn from_str(s: &str) -> Result<Self, Self::Err> {
58        match s {
59            "" => Err(ParseError::Empty),
60            "+" => Ok(Self::Forward),
61            "-" => Ok(Self::Reverse),
62            _ => Err(ParseError::Invalid),
63        }
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_fmt() {
73        assert_eq!(Strand::Forward.to_string(), "+");
74        assert_eq!(Strand::Reverse.to_string(), "-");
75    }
76
77    #[test]
78    fn test_from_str() {
79        assert_eq!("+".parse(), Ok(Strand::Forward));
80        assert_eq!("-".parse(), Ok(Strand::Reverse));
81
82        assert_eq!("".parse::<Strand>(), Err(ParseError::Empty));
83        assert_eq!("ndls".parse::<Strand>(), Err(ParseError::Invalid));
84    }
85}