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