1use std::{error, fmt, str::FromStr};
4
5use bincode::{Decode, Encode};
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9#[derive(Encode, Decode, Clone, Copy, Debug, Eq, PartialEq, PartialOrd, Ord)]
11#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
12pub enum Strand {
13 Forward,
15 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#[derive(Clone, Debug, Eq, PartialEq)]
36pub enum ParseError {
37 Empty,
39 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}