1use std::{
2 convert::Infallible,
3 fmt::{self, Display, Formatter},
4 str::FromStr,
5};
6
7use str_reader::StringReader;
8
9use crate::ParseError;
10
11#[derive(Clone)]
13pub enum BandwidthType {
14 AS,
15 CT,
16 Other(String),
17}
18
19impl Display for BandwidthType {
20 #[inline]
21 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
22 let s = match self {
23 Self::AS => "AS",
24 Self::CT => "CT",
25 Self::Other(t) => t.as_str(),
26 };
27
28 f.write_str(s)
29 }
30}
31
32impl FromStr for BandwidthType {
33 type Err = Infallible;
34
35 fn from_str(s: &str) -> Result<Self, Self::Err> {
36 let res = match s {
37 "AS" => Self::AS,
38 "CT" => Self::CT,
39 _ => Self::Other(s.to_string()),
40 };
41
42 Ok(res)
43 }
44}
45
46#[derive(Clone)]
48pub struct Bandwidth {
49 bandwidth_type: BandwidthType,
50 bandwidth: u32,
51}
52
53impl Bandwidth {
54 #[inline]
56 pub fn new(bandwidth_type: BandwidthType, bandwidth: u32) -> Self {
57 Self {
58 bandwidth_type,
59 bandwidth,
60 }
61 }
62
63 #[inline]
65 pub fn bandwidth_type(&self) -> &BandwidthType {
66 &self.bandwidth_type
67 }
68
69 #[inline]
71 pub fn bandwidth(&self) -> u32 {
72 self.bandwidth
73 }
74}
75
76impl Display for Bandwidth {
77 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
78 write!(f, "{}:{}", self.bandwidth_type, self.bandwidth)
79 }
80}
81
82impl FromStr for Bandwidth {
83 type Err = ParseError;
84
85 fn from_str(s: &str) -> Result<Self, Self::Err> {
86 let mut reader = StringReader::new(s);
87
88 let bandwidth_type = reader.read_until(|c| c == ':').trim().parse()?;
89
90 reader.match_char(':')?;
91
92 let bandwidth = reader.read_u32()?;
93
94 reader.skip_whitespace();
95
96 if !reader.is_empty() {
97 return Err(ParseError::plain());
98 }
99
100 Ok(Self::new(bandwidth_type, bandwidth))
101 }
102}