use super::{find_tag, Packet, Tag};
#[derive(Debug)]
pub enum Response {
CommandResponse(Vec<Packet>),
Event(Packet),
}
pub struct ResponseBuilder {
response: Vec<Packet>,
in_packet: Packet,
in_response_sequence: bool,
}
impl ResponseBuilder {
pub fn new() -> ResponseBuilder {
Self {
response: vec![],
in_packet: vec![],
in_response_sequence: false,
}
}
pub fn add_line(&mut self, line: &str) -> Option<Response> {
if line.is_empty() {
if !self.in_response_sequence
&& !self.in_packet.is_empty()
&& self.in_packet[0].key.eq_ignore_ascii_case("Event")
{
let data = self.in_packet.clone();
self.in_packet.clear();
return Some(Response::Event(data));
} else {
self.response.push(self.in_packet.clone());
let event_list =
find_tag(&self.in_packet, "EventList").cloned();
self.in_packet.clear();
if let Some(el_val) = event_list {
if el_val.eq_ignore_ascii_case("start") {
self.in_response_sequence = true;
} else if el_val.eq_ignore_ascii_case("Complete") {
self.in_response_sequence = false;
}
}
if !self.in_response_sequence {
let data = self.response.clone();
self.response.clear();
return Some(Response::CommandResponse(data));
}
}
} else {
if let Some(tag) = line_to_tag(line) {
self.in_packet.push(tag);
}
}
None
}
}
fn line_to_tag(line: &str) -> Option<Tag> {
line.find(':').map(|pos| {
let key = &line[0..pos];
let value = &line[pos + 1..].trim();
Tag::from(key, value)
})
}