Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Moving to websockets over streams #19

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ lazy_static = "1.4.0"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["json"] }
tracing-appender = "0.2.3"
actix-ws = "0.2.5"
actix-rt = "2.9.0"

[dev-dependencies]
criterion = { version = "0.4", features = ["html_reports"] }
Expand Down
3 changes: 2 additions & 1 deletion backend/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
env::PACKAGE_VERSION,
err::Error,
event::Event,
sdcard::{get_card_cid, is_card_inserted},
sdcard::{get_card_cid, is_card_inserted}, ws::ws,
};
use actix_web::{
delete, get, http::StatusCode, post, web, Either, HttpResponse, HttpResponseBuilder, Responder,
Expand All @@ -19,6 +19,7 @@ use tracing::{instrument, trace};

pub(crate) fn config(cfg: &mut web::ServiceConfig) {
cfg //
.service(ws)
.service(health)
.service(version)
.service(listen)
Expand Down
4 changes: 2 additions & 2 deletions backend/src/dto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
120 changes: 95 additions & 25 deletions backend/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
use std::marker::PhantomData;

use actix_web::web::Bytes;
use tracing::warn;

pub(crate) struct Event<T: EventTrait>(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<T: EventTrait> Event<T> {
impl<'a, T: EventTrait<'a>> Event<'a, T> {
pub fn new(val: T) -> Self {
Event(val)
Event(val, PhantomData)
}
}

impl<T: EventTrait> ToString for Event<T> {
impl<'a, T: EventTrait<'a>> ToString for Event<'a, T> {
fn to_string(&self) -> String {
let mut output = "".to_string();

Expand All @@ -42,55 +45,122 @@ impl<T: EventTrait> ToString for Event<T> {
}
}

impl<T: EventTrait> From<Event<T>> for Bytes {
fn from(val: Event<T>) -> Self {
impl<'a, T: EventTrait<'a>> From<Event<'a, T>> for Bytes {
fn from(val: Event<'a, T>) -> Self {
Bytes::from(val.to_string())
}
}

impl<T: EventTrait> From<T> for Event<T> {
fn from(value: T) -> Self {
Event(value)
impl<'a, T: EventTrait<'a>> From<Event<'a, T>> for String {
fn from(val: Event<'a, T>) -> Self {
val.to_string()
}
}

pub(crate) struct EventBuilder {
id: Option<&'static str>,
event: Option<&'static str>,
data: Option<&'static str>,
impl<'a, T: EventTrait<'a>> From<T> for Event<'a, T> {
fn from(value: T) -> Self {
Event(value, PhantomData)
}
}
#[derive(Debug)]
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,
event: None,
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
}
}

#[derive(Debug)]
pub struct ParsedEvent<'a>(EventBuilder<'a>);

impl<'a> ParsedEvent<'a> {
pub fn parse(str: &'a str) -> ParsedEvent<'a> {
let mut event = EventBuilder::new();

for line in str.split("\n") {
let (key, mut 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;
}

value = value.trim();

match key {
"id" => event.set_id(value),
"event" => event.set_event(value),
"data" => event.set_data(value),
_ => {
warn!(key = key, "Invalid key provided");
continue;
}
};
}

ParsedEvent(event)
}
}

impl<'a> EventTrait<'a> for ParsedEvent<'a> {
fn get_id(&self) -> Option<&'a str> {
self.0.get_id()
}

fn get_event(&self) -> Option<&'a str> {
self.0.get_event()
}

fn get_data(&self) -> Option<&'a str> {
self.0.get_data()
}
}
4 changes: 3 additions & 1 deletion backend/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ pub fn create_subscriber() {

if cfg!(debug_assertions) {
subscriber
.with(tracing_subscriber::fmt::layer().pretty())
.with(tracing_subscriber::fmt::layer().pretty().with_filter(
tracing_subscriber::filter::LevelFilter::from_level(CONFIG.log_level),
))
.init();
} else {
subscriber.init();
Expand Down
2 changes: 2 additions & 0 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ mod log;
mod sdcard;
mod steam;
mod watch;
mod ws;

use crate::cfg::CONFIG;
use crate::ds::Store;
use crate::env::*;
Expand Down
Loading
Loading