use crate::{error::QuicP2pError, utils, R};
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use std::{fmt, net::SocketAddr};
use unwrap::unwrap;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum WireMsg {
Handshake(Handshake),
EndpointEchoReq,
EndpointEchoResp(SocketAddr),
UserMsg(Bytes),
}
const USER_MSG_FLAG: u8 = 0;
impl Into<(Bytes, u8)> for WireMsg {
fn into(self) -> (Bytes, u8) {
match self {
WireMsg::UserMsg(ref m) => (m.clone(), USER_MSG_FLAG),
_ => (
From::from(unwrap!(bincode::serialize(&self))),
!USER_MSG_FLAG,
),
}
}
}
impl WireMsg {
pub fn from_raw(mut raw: Vec<u8>) -> R<Self> {
let msg_flag = raw.pop();
match msg_flag {
Some(flag) if flag == USER_MSG_FLAG => Ok(WireMsg::UserMsg(From::from(raw))),
Some(flag) if flag == !USER_MSG_FLAG => Ok(bincode::deserialize(&raw)?),
_x => Err(QuicP2pError::InvalidWireMsgFlag),
}
}
}
impl fmt::Display for WireMsg {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
WireMsg::UserMsg(ref m) => {
write!(f, "WireMsg::UserMsg({})", utils::bin_data_format(&*m))
}
WireMsg::EndpointEchoReq => write!(f, "WireMsg::EndpointEchoReq"),
WireMsg::EndpointEchoResp(ref sa) => write!(f, "WireMsg::EndpointEchoResp({})", sa),
WireMsg::Handshake(ref hs) => write!(f, "WireMsg::Handshake({})", hs),
}
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub enum Handshake {
Node,
Client,
}
impl fmt::Display for Handshake {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Handshake::Node => write!(f, "Handshake::Node",),
Handshake::Client => write!(f, "Handshake::Client"),
}
}
}