1pub mod parser;
3pub mod socket;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub enum Response {
9 Ok,
11 OkVal(String),
13 Err(String),
15}
16
17impl From<&str> for Response {
19 fn from(s: &str) -> Self {
20 let mut s_parts = s.split_whitespace();
21 if s_parts.next() != Some("OK") {
22 return Self::Err(s.to_string());
23 }
24 match s_parts.next() {
25 Some(val) => {
26 let msg = std::iter::once(val)
27 .chain(s_parts)
28 .collect::<Vec<_>>()
29 .join(" ");
30 Self::OkVal(msg)
31 }
32 None => Self::Ok,
33 }
34 }
35}
36
37#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42pub struct Irq {
43 pub line: usize,
45 pub state: IrqState,
47}
48
49impl Irq {
50 pub fn new(line: usize, state: IrqState) -> Self {
52 Irq { line, state }
53 }
54}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
58pub enum IrqState {
59 Raise,
61 Lower,
63}
64
65impl TryFrom<&str> for Irq {
66 type Error = &'static str;
67
68 fn try_from(s: &str) -> Result<Self, Self::Error> {
69 let mut s_parts = s.split_whitespace();
70
71 if s_parts.next() != Some("IRQ") {
72 return Err("Invalid IRQ string");
73 }
74 let ty = match s_parts.next() {
75 Some("raise") => IrqState::Raise,
76 Some("lower") => IrqState::Lower,
77 _ => return Err("Invalid IRQ type"),
78 };
79 let line = s_parts
80 .next()
81 .ok_or("Invalid IRQ line")?
82 .parse()
83 .map_err(|_| "Invalid IRQ line")?;
84
85 match s_parts.next() {
86 Some(_) => Err("Invalid IRQ string"),
87 None => Ok(Irq::new(line, ty)),
88 }
89 }
90}
91
92#[cfg(test)]
93mod test {
94 use super::*;
95
96 #[test]
97 fn test_response_from() {
98 let response = Response::from("OK");
99 assert_eq!(response, Response::Ok);
100
101 let response = Response::from("OK val");
102 assert_eq!(response, Response::OkVal("val".to_string()));
103
104 let response = Response::from("ERR error");
105 assert_eq!(response, Response::Err("ERR error".to_string()));
106 }
107
108 #[test]
109 fn test_irq_try_from() {
110 let irq = Irq::try_from("invalid");
111 assert_eq!(irq, Err("Invalid IRQ string"));
112
113 let irq = Irq::try_from("IRQ invalid");
114 assert_eq!(irq, Err("Invalid IRQ type"));
115
116 let irq = Irq::try_from("IRQ raise -1");
117 assert_eq!(irq, Err("Invalid IRQ line"));
118
119 let irq = Irq::try_from("IRQ raise 1 invalid");
120 assert_eq!(irq, Err("Invalid IRQ string"));
121
122 let irq = Irq::try_from("IRQ raise 1");
123 assert_eq!(irq, Ok(Irq::new(1, IrqState::Raise)));
124
125 let irq = Irq::try_from("IRQ lower 2");
126 assert_eq!(irq, Ok(Irq::new(2, IrqState::Lower)));
127 }
128}