noodles_gff/directive_buf/value/
genome_build.rs1use std::{error, fmt, str::FromStr};
4
5use bstr::{BStr, BString};
6
7#[derive(Clone, Debug, Eq, PartialEq)]
9pub struct GenomeBuild {
10 source: BString,
11 name: BString,
12}
13
14impl GenomeBuild {
15 pub fn new<S, N>(source: S, name: N) -> Self
24 where
25 S: Into<BString>,
26 N: Into<BString>,
27 {
28 Self {
29 source: source.into(),
30 name: name.into(),
31 }
32 }
33
34 pub fn source(&self) -> &BStr {
44 self.source.as_ref()
45 }
46
47 pub fn name(&self) -> &BStr {
57 self.name.as_ref()
58 }
59}
60
61impl fmt::Display for GenomeBuild {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 write!(f, "{} {}", self.source, self.name)
64 }
65}
66
67#[derive(Clone, Debug, Eq, PartialEq)]
69pub enum ParseError {
70 Empty,
72 MissingSource,
74 MissingName,
76}
77
78impl error::Error for ParseError {}
79
80impl fmt::Display for ParseError {
81 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
82 f.write_str("invalid genome build directive: ")?;
83
84 match self {
85 Self::Empty => f.write_str("empty input"),
86 Self::MissingSource => f.write_str("missing source"),
87 Self::MissingName => f.write_str("missing name"),
88 }
89 }
90}
91
92impl FromStr for GenomeBuild {
93 type Err = ParseError;
94
95 fn from_str(s: &str) -> Result<Self, Self::Err> {
96 if s.is_empty() {
97 return Err(ParseError::Empty);
98 }
99
100 let mut args = s.split_ascii_whitespace();
101 let source = args.next().ok_or(ParseError::MissingSource)?;
102 let name = args.next().ok_or(ParseError::MissingName)?;
103
104 Ok(Self::new(source, name))
105 }
106}
107
108#[cfg(test)]
109mod tests {
110 use super::*;
111
112 #[test]
113 fn test_fmt() {
114 let genome_build = GenomeBuild::new("NDLS", "r1");
115 assert_eq!(genome_build.to_string(), "NDLS r1");
116 }
117
118 #[test]
119 fn test_from_str() -> Result<(), ParseError> {
120 assert_eq!("NDLS r1".parse(), Ok(GenomeBuild::new("NDLS", "r1")));
121
122 assert_eq!("".parse::<GenomeBuild>(), Err(ParseError::Empty));
123 assert_eq!("NDLS".parse::<GenomeBuild>(), Err(ParseError::MissingName));
124
125 Ok(())
126 }
127}