[feat][code] proto crate, one stream per request

This commit is contained in:
2024-11-08 22:22:50 +01:00
parent 04a39790b8
commit 9d8f579a0f
18 changed files with 862 additions and 306 deletions

View File

@ -0,0 +1,22 @@
[package]
name = "lanspread-proto"
version = "0.1.0"
edition = "2021"
[lints.rust]
unsafe_code = "forbid"
[lints.clippy]
pedantic = { level = "warn", priority = -1 }
todo = "warn"
unwrap_used = "warn"
[dependencies]
# local
lanspread-db = { path = "../lanspread-db" }
# external
bytes = "1.8"
serde = { workspace = true }
serde_json = { workspace = true }
tracing = { workspace = true }

View File

@ -0,0 +1,87 @@
use bytes::Bytes;
use lanspread_db::db::Game;
use serde::{Deserialize, Serialize};
use tracing::error;
#[derive(Debug, Serialize, Deserialize)]
pub enum Request {
ListGames,
GetGame { id: u64 },
Invalid(Vec<u8>, String),
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Response {
Games(Vec<Game>),
Game(Game),
GameNotFound(u64),
InvalidRequest(Vec<u8>, String),
EncodingError(String),
DecodingError(Vec<u8>, String),
}
// Add Message trait
pub trait Message {
fn decode(bytes: &[u8]) -> Self;
fn encode(&self) -> Bytes;
}
// Implement for Request
impl Message for Request {
fn decode(bytes: &[u8]) -> Self {
match serde_json::from_slice(bytes) {
Ok(t) => t,
Err(e) => {
tracing::error!(
"got invalid request from client (error: {}): {}",
e,
String::from_utf8_lossy(bytes)
);
Request::Invalid(bytes.into(), e.to_string())
}
}
}
fn encode(&self) -> Bytes {
match serde_json::to_vec(self) {
Ok(s) => Bytes::from(s),
Err(e) => {
error!(?e, "Request encoding error");
Bytes::from(format!(r#"{{"error": "encoding error: {e}"}}"#))
}
}
}
}
// Implement for Response
impl Message for Response {
fn decode(bytes: &[u8]) -> Self {
match serde_json::from_slice(bytes) {
Ok(t) => t,
Err(e) => Response::DecodingError(bytes.into(), e.to_string()),
}
}
fn encode(&self) -> Bytes {
match serde_json::to_vec(self) {
Ok(s) => Bytes::from(s),
Err(e) => {
error!(?e, "Response encoding error");
Bytes::from(format!(r#"{{"error": "encoding error: {e}"}}"#))
}
}
}
}
// Helper methods for Response
impl Response {
#[must_use]
pub fn games(games: Vec<Game>) -> Self {
Response::Games(games)
}
#[must_use]
pub fn game(game: Game) -> Self {
Response::Game(game)
}
}