diff --git a/backend/src/dto.rs b/backend/src/dto.rs index 2239f6f..9471101 100644 --- a/backend/src/dto.rs +++ b/backend/src/dto.rs @@ -8,8 +8,8 @@ pub enum CardEvent { Updated, } -impl EventTrait for CardEvent { - fn get_event(&self) -> Option<&'static str> { +impl<'a> EventTrait<'a> for CardEvent { + fn get_event(&self) -> Option<&'a str> { Some(match self { CardEvent::Inserted => "insert", CardEvent::Removed => "remove", diff --git a/backend/src/event.rs b/backend/src/event.rs index be876f5..ac492ea 100644 --- a/backend/src/event.rs +++ b/backend/src/event.rs @@ -1,26 +1,60 @@ +use std::marker::PhantomData; + use actix_web::web::Bytes; +use tracing::warn; -pub(crate) struct Event(T); +pub(crate) struct Event<'a, T: EventTrait<'a>>(T, PhantomData<&'a T>); -pub(crate) trait EventTrait { - fn get_id(&self) -> Option<&'static str> { +pub(crate) trait EventTrait<'a> { + fn get_id(&self) -> Option<&'a str> { None } - fn get_event(&self) -> Option<&'static str> { + fn get_event(&self) -> Option<&'a str> { None } - fn get_data(&self) -> Option<&'static str> { + fn get_data(&self) -> Option<&'a str> { None } } -impl Event { - pub fn new(val: T) -> Self { - Event(val) +impl<'a, T: EventTrait<'a>> Event<'a, T> { + pub fn new(val: T) -> Self { + Event(val, PhantomData) + } + + pub fn parse(str: &'a str) -> impl EventTrait + 'a { + let mut event = EventBuilder::new(); + + for line in str.split("\n") { + let (key, value) = match line.split_once(":") { + None => { + warn!(line = line, "Malformed Event detected"); + continue; + } + Some(key) => key, + }; + + if value.is_empty() { + warn!(key = key, "Event had empty data"); + continue; + } + + match key { + "id" => event.set_id(value), + "event" => event.set_event(value), + "data" => event.set_data(value), + _ => { + warn!(key=key, "Invalid key provided"); + continue + } + }; + } + + event } } -impl ToString for Event { +impl<'a, T: EventTrait<'a>> ToString for Event<'a, T> { fn to_string(&self) -> String { let mut output = "".to_string(); @@ -42,32 +76,32 @@ impl ToString for Event { } } -impl From> for Bytes { - fn from(val: Event) -> Self { +impl<'a, T: EventTrait<'a>> From> for Bytes { + fn from(val: Event<'a, T>) -> Self { Bytes::from(val.to_string()) } } -impl From> for String { - fn from(val: Event) -> Self { +impl<'a, T: EventTrait<'a>> From> for String { + fn from(val: Event<'a, T>) -> Self { val.to_string() } } -impl From for Event { +impl<'a, T: EventTrait<'a>> From for Event<'a, T> { fn from(value: T) -> Self { - Event(value) + Event(value, PhantomData) } } -pub(crate) struct EventBuilder { - id: Option<&'static str>, - event: Option<&'static str>, - data: Option<&'static str>, +pub(crate) struct EventBuilder<'a> { + id: Option<&'a str>, + event: Option<&'a str>, + data: Option<&'a str>, } #[allow(dead_code)] -impl EventBuilder { +impl <'a>EventBuilder<'a> { pub fn new() -> Self { EventBuilder { id: None, @@ -75,28 +109,37 @@ impl EventBuilder { data: None, } } - pub fn with_id(mut self, id: &'static str) -> Self { + pub fn with_id(mut self, id: &'a str) -> Self { self.id = Some(id); self } - pub fn with_event(mut self, event: &'static str) -> Self { + pub fn set_id(&mut self, id: &'a str) { + self.id = Some(id); + } + pub fn with_event(mut self, event: &'a str) -> Self { self.event = Some(event); self } - pub fn with_data(mut self, data: &'static str) -> Self { + pub fn set_event(&mut self, event: &'a str) { + self.event = Some(event); + } + pub fn with_data(mut self, data: &'a str) -> Self { self.data = Some(data); self } + pub fn set_data(&mut self, data: &'a str) { + self.data = Some(data); + } } -impl EventTrait for EventBuilder { - fn get_data(&self) -> Option<&'static str> { +impl <'a> EventTrait<'a> for EventBuilder<'a> { + fn get_data(&self) -> Option<&'a str> { self.data } - fn get_event(&self) -> Option<&'static str> { + fn get_event(&self) -> Option<&'a str> { self.event } - fn get_id(&self) -> Option<&'static str> { + fn get_id(&self) -> Option<&'a str> { self.id } }