Structure packets better
This commit is contained in:
parent
5cf0f76477
commit
73ffae3898
3 changed files with 78 additions and 18 deletions
|
|
@ -1,25 +1,43 @@
|
|||
mod macros;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use self::macros::packets;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Id(pub u128);
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct HelloCmd {
|
||||
pub id: Id,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct HelloRpl {
|
||||
pub msg: String,
|
||||
#[serde(tag = "type")]
|
||||
pub enum HelloRpl {
|
||||
Success { id: Id },
|
||||
InvalidName { reason: String },
|
||||
NameAlreadyUsed,
|
||||
}
|
||||
|
||||
// Create a Cmd enum for all commands and a Rpl enum for all replies, as well as
|
||||
// TryFrom impls for the individual command and reply structs.
|
||||
packets! {
|
||||
Hello(HelloCmd, HelloRpl),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Data {
|
||||
HelloCmd(HelloCmd),
|
||||
HelloRpl(HelloRpl),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct Packet {
|
||||
pub id: u64,
|
||||
pub enum Packet {
|
||||
Cmd {
|
||||
id: u64,
|
||||
#[serde(flatten)]
|
||||
pub data: Data,
|
||||
cmd: Cmd,
|
||||
},
|
||||
Rpl {
|
||||
id: u64,
|
||||
#[serde(flatten)]
|
||||
rpl: Rpl,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
43
cove-core/src/macros.rs
Normal file
43
cove-core/src/macros.rs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
macro_rules! packets {
|
||||
( $( $name:ident($cmd:ident, $rpl:ident), )* ) => {
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "name", content = "data")]
|
||||
pub enum Cmd {
|
||||
$( $name($cmd), )*
|
||||
}
|
||||
|
||||
$(
|
||||
impl std::convert::TryFrom<Cmd> for $cmd {
|
||||
type Error = ();
|
||||
fn try_from(cmd: Cmd) -> Result<Self, Self::Error> {
|
||||
match cmd {
|
||||
Cmd::$name(val) => Ok(val),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(tag = "name", content = "data")]
|
||||
pub enum Rpl {
|
||||
$( $name($rpl), )*
|
||||
}
|
||||
|
||||
$(
|
||||
impl std::convert::TryFrom<Rpl> for $rpl {
|
||||
type Error = ();
|
||||
fn try_from(rpl: Rpl) -> Result<Self, Self::Error> {
|
||||
match rpl {
|
||||
Rpl::$name(val) => Ok(val),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
// Make macro importable from elsewhere
|
||||
// See https://stackoverflow.com/a/31749071
|
||||
pub(crate) use packets;
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
use cove_core::{Data, HelloCmd, Packet};
|
||||
use cove_core::{HelloCmd, HelloRpl, Id, Packet, Rpl};
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
let packet = Packet {
|
||||
let packet = Packet::Rpl {
|
||||
id: 1337,
|
||||
data: Data::HelloCmd(HelloCmd {
|
||||
name: "Garmy".to_string(),
|
||||
rpl: Rpl::Hello(HelloRpl::InvalidName {
|
||||
reason: "abc".to_string(),
|
||||
}),
|
||||
};
|
||||
println!("{}", serde_json::to_string(&packet).unwrap());
|
||||
println!("{}", serde_json::to_string_pretty(&packet).unwrap());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue