trillium_http/
priority.rs1mod parse;
12
13use std::{
14 fmt::{self, Display, Formatter},
15 str::FromStr,
16};
17
18const DEFAULT_URGENCY: u8 = 3;
19const MAX_URGENCY: u8 = 7;
20
21#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
31pub struct Priority {
32 urgency: u8,
33 incremental: bool,
34}
35
36impl Default for Priority {
37 fn default() -> Self {
38 Self {
39 urgency: DEFAULT_URGENCY,
40 incremental: false,
41 }
42 }
43}
44
45impl Priority {
46 #[must_use]
50 #[cfg(test)] pub fn new(urgency: u8) -> Self {
52 Self {
53 urgency: urgency.min(MAX_URGENCY),
54 incremental: false,
55 }
56 }
57
58 #[must_use]
60 pub const fn urgency(self) -> u8 {
61 self.urgency
62 }
63
64 #[must_use]
66 pub const fn is_incremental(self) -> bool {
67 self.incremental
68 }
69
70 #[must_use]
72 #[cfg(test)] pub fn with_urgency(mut self, urgency: u8) -> Self {
74 self.urgency = urgency.min(MAX_URGENCY);
75 self
76 }
77
78 #[must_use]
80 #[cfg(test)] pub const fn with_incremental(mut self, incremental: bool) -> Self {
82 self.incremental = incremental;
83 self
84 }
85
86 #[must_use]
89 pub fn parse(s: &str) -> Self {
90 parse::parse(s)
91 }
92}
93
94impl FromStr for Priority {
95 type Err = std::convert::Infallible;
96
97 fn from_str(s: &str) -> Result<Self, Self::Err> {
99 Ok(Self::parse(s))
100 }
101}
102
103impl Display for Priority {
104 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
105 write!(f, "u={}", self.urgency)?;
106 if self.incremental {
107 f.write_str(", i")?;
108 }
109 Ok(())
110 }
111}
112
113#[cfg(test)]
114mod test {
115 use super::Priority;
116
117 #[test]
118 fn defaults() {
119 let p = Priority::default();
120 assert_eq!(p.urgency(), 3);
121 assert!(!p.is_incremental());
122 }
123
124 #[test]
125 fn constructors_clamp() {
126 assert_eq!(Priority::new(5).urgency(), 5);
127 assert_eq!(Priority::new(200).urgency(), 7);
128 assert_eq!(Priority::default().with_urgency(99).urgency(), 7);
129 assert!(Priority::new(0).with_incremental(true).is_incremental());
130 }
131
132 #[test]
133 fn display_roundtrip() {
134 assert_eq!(Priority::new(3).to_string(), "u=3");
135 assert_eq!(
136 Priority::new(0).with_incremental(true).to_string(),
137 "u=0, i"
138 );
139 for urgency in 0..=7 {
140 for incremental in [false, true] {
141 let p = Priority::new(urgency).with_incremental(incremental);
142 assert_eq!(p.to_string().parse::<Priority>().unwrap(), p);
143 }
144 }
145 }
146}