1use serde::{Deserialize, Serialize};
2use std::fmt;
3use std::str::FromStr;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, Default)]
8#[serde(rename_all = "lowercase")]
9pub enum Level {
10 Lite,
11 #[default]
12 Full,
13 Ultra,
14}
15
16impl Level {
17 pub fn head_limit(&self, base: usize) -> usize {
20 match self {
21 Level::Lite => base * 2,
22 Level::Full => base,
23 Level::Ultra => (base / 2).max(5),
24 }
25 }
26}
27
28impl fmt::Display for Level {
29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
30 match self {
31 Level::Lite => write!(f, "lite"),
32 Level::Full => write!(f, "full"),
33 Level::Ultra => write!(f, "ultra"),
34 }
35 }
36}
37
38impl FromStr for Level {
39 type Err = String;
40
41 fn from_str(s: &str) -> Result<Self, Self::Err> {
42 match s.to_lowercase().as_str() {
43 "lite" => Ok(Level::Lite),
44 "full" => Ok(Level::Full),
45 "ultra" => Ok(Level::Ultra),
46 _ => Err(format!("unknown level: {s} (expected: lite, full, ultra)")),
47 }
48 }
49}
50
51#[cfg(test)]
52mod tests {
53 use super::*;
54
55 #[test]
56 fn head_limit_lite() {
57 assert_eq!(Level::Lite.head_limit(40), 80);
58 }
59
60 #[test]
61 fn head_limit_full() {
62 assert_eq!(Level::Full.head_limit(40), 40);
63 }
64
65 #[test]
66 fn head_limit_ultra() {
67 assert_eq!(Level::Ultra.head_limit(40), 20);
68 }
69
70 #[test]
71 fn head_limit_ultra_minimum() {
72 assert_eq!(Level::Ultra.head_limit(8), 5);
74 }
75
76 #[test]
77 fn from_str() {
78 assert_eq!("lite".parse::<Level>().unwrap(), Level::Lite);
79 assert_eq!("FULL".parse::<Level>().unwrap(), Level::Full);
80 assert_eq!("Ultra".parse::<Level>().unwrap(), Level::Ultra);
81 assert!("invalid".parse::<Level>().is_err());
82 }
83
84 #[test]
85 fn display() {
86 assert_eq!(Level::Lite.to_string(), "lite");
87 assert_eq!(Level::Full.to_string(), "full");
88 assert_eq!(Level::Ultra.to_string(), "ultra");
89 }
90}