use bitcode::{Decode, DecodeOwned, Encode};
use flagset::{flags, FlagSet};
use parking_lot::{Condvar, Mutex};
use std::convert::Infallible;
use std::error::Error;
use std::fmt::Debug;
use std::future::Future;
use std::num::NonZeroU64;
use std::pin::Pin;
use std::sync::{Arc, Weak};
use std::task::{Context, Poll, Waker};
use crate::net::{Connection, NetworkingError};
pub(super) mod dispatch;
pub mod queue;
#[cfg(feature = "derive")]
pub use gtether_derive::MessageBody;
#[derive(Debug, thiserror::Error)]
#[error("Could not serialize message data; {details}")]
pub struct MessageEncodeError {
details: String,
#[source]
source: Box<dyn Error + Send + Sync>,
}
impl From<MessageEncodeError> for NetworkingError {
#[inline]
fn from(value: MessageEncodeError) -> Self {
Self::MalformedMessage(Box::new(value))
}
}
#[derive(Debug, thiserror::Error)]
#[error("Could not deserialize message data; {details}")]
pub struct MessageDecodeError {
details: String,
#[source]
source: Option<Box<dyn Error + Send + Sync>>,
}
impl From<MessageDecodeError> for NetworkingError {
#[inline]
fn from(value: MessageDecodeError) -> Self {
Self::MalformedMessage(Box::new(value))
}
}
flags! {
pub enum MessageFlags: u16 {
Reliable,
}
}
#[derive(Encode, Decode, Debug, Clone, PartialEq, Eq)]
pub struct MessageHeader {
key: String,
msg_num: Option<NonZeroU64>,
reply_num: Option<NonZeroU64>,
}
impl MessageHeader {
#[inline]
pub fn key(&self) -> &str {
&self.key
}
#[inline]
pub fn msg_num(&self) -> Option<NonZeroU64> {
self.msg_num
}
#[inline]
pub fn reply_num(&self) -> Option<NonZeroU64> {
self.reply_num
}
pub(in crate::net) fn encode(&self) -> impl Iterator<Item=u8> {
let bytes = bitcode::encode(self);
let len = bytes.len() as u16;
len.to_be_bytes().into_iter()
.chain(bytes)
}
pub(in crate::net) fn decode(bytes: &[u8]) -> Result<(Self, &[u8]), MessageDecodeError> {
let header_len = if bytes.len() >= 2 {
u16::from_be_bytes(bytes[0..2].try_into()
.map_err(|err| MessageDecodeError {
details: "Could not deserialize message header length".to_owned(),
source: Some(Box::new(err)),
})?)
} else {
return Err(MessageDecodeError {
details: format!("Not enough bytes to parse header length ({} < 2)", bytes.len()),
source: None,
});
};
let full_len = header_len as usize + 2;
if bytes.len() >= full_len {
let header = bitcode::decode(&bytes[2..full_len])
.map_err(|err| MessageDecodeError {
details: "Could not deserialize message header".to_owned(),
source: Some(Box::new(err)),
})?;
Ok((header, &bytes[full_len..]))
} else {
Err(MessageDecodeError {
details: format!("Not enough bytes to parse header ({} < {})", bytes.len(), full_len),
source: None,
})
}
}
}
pub trait MessageBody {
const KEY: &'static str;
fn flags() -> FlagSet<MessageFlags> {
FlagSet::default()
}
}
pub trait MessageSend: MessageBody {
type EncodeError: Error + Send + Sync + 'static;
fn encode(&self) -> Result<Vec<u8>, Self::EncodeError>;
}
impl<M: MessageBody + Encode> MessageSend for M {
type EncodeError = Infallible;
#[inline]
fn encode(&self) -> Result<Vec<u8>, Self::EncodeError> {
Ok(bitcode::encode(self))
}
}
pub trait MessageRecv: MessageBody {
type DecodeError: Error + Send + Sync + 'static;
fn decode(bytes: &[u8]) -> Result<Self, Self::DecodeError>
where
Self: Sized;
}
impl<M: MessageBody + DecodeOwned> MessageRecv for M {
type DecodeError = bitcode::Error;
#[inline]
fn decode(bytes: &[u8]) -> Result<Self, Self::DecodeError>
where
Self: Sized,
{
Ok(bitcode::decode(bytes)?)
}
}
pub trait MessageRepliable: MessageBody {
type Reply: MessageBody;
}
#[derive(Debug, PartialEq, Eq)]
pub struct Message<M: MessageBody> {
header: MessageHeader,
body: M,
}
impl<M: MessageBody> Message<M> {
#[inline]
pub fn new(body: M) -> Self {
let header = MessageHeader {
key: M::KEY.to_owned(),
msg_num: None,
reply_num: None,
};
Self {
header,
body,
}
}
#[inline]
pub(super) fn with_header(header: MessageHeader, body: M) -> Self {
Self {
header,
body,
}
}
#[inline]
pub fn header(&self) -> &MessageHeader {
&self.header
}
#[inline]
pub fn body(&self) -> &M {
&self.body
}
#[inline]
pub fn into_body(self) -> M {
self.body
}
pub(super) fn set_msg_num(&mut self, msg_num: NonZeroU64) {
self.header.msg_num = Some(msg_num);
}
}
impl<M: MessageSend> Message<M> {
pub fn encode(&self) -> Result<Vec<u8>, MessageEncodeError> {
let body = self.body.encode()
.map_err(|err| MessageEncodeError {
details: "Could not serialize message body".to_owned(),
source: Box::new(err)
})?;
Ok(self.header.encode()
.chain(body)
.collect::<Vec<_>>())
}
}
impl<M: MessageRepliable> Message<M> {
#[inline]
pub fn reply(&self, body: M::Reply) -> Message<M::Reply> {
let header = MessageHeader {
key: M::Reply::KEY.to_owned(),
msg_num: None,
reply_num: self.header.msg_num,
};
Message {
header,
body,
}
}
}
impl<M: MessageBody> From<M> for Message<M> {
#[inline]
fn from(value: M) -> Self {
Message::new(value)
}
}
pub(in crate::net) struct MessageReplyContext<M: MessageRecv> {
value: Mutex<Option<Message<M>>>,
waker: Mutex<Option<Waker>>,
cvar: Condvar,
}
impl<M: MessageRecv> MessageReplyContext<M> {
fn new() -> Self {
Self {
value: Mutex::new(None),
waker: Mutex::new(None),
cvar: Condvar::new(),
}
}
fn accept(&self, msg: Message<M>) {
let mut value = self.value.lock();
*value = Some(msg);
if let Some(waker) = self.waker.lock().take() {
waker.wake();
}
self.cvar.notify_one();
}
}
pub struct MessageReplyFuture<M: MessageRecv> {
ctx: Arc<MessageReplyContext<M>>,
}
impl<M: MessageRecv> MessageReplyFuture<M> {
pub fn wait(self) -> Message<M> {
let mut msg = self.ctx.value.lock();
if let Some(msg) = msg.take() {
msg
} else {
self.ctx.cvar.wait(&mut msg);
msg.take().expect("'msg' should be set after cvar wakes")
}
}
}
impl<M: MessageRecv> Future for MessageReplyFuture<M> {
type Output = Message<M>;
fn poll(self: Pin<&mut Self>, ctx: &mut Context<'_>) -> Poll<Self::Output> {
if let Some(msg) = self.ctx.value.lock().take() {
Poll::Ready(msg)
} else {
let mut waker = self.ctx.waker.lock();
if let Some(waker) = waker.as_mut() {
waker.clone_from(ctx.waker());
} else {
*waker = Some(ctx.waker().clone());
}
Poll::Pending
}
}
}
#[derive(Debug, thiserror::Error)]
pub enum MessageDispatchError {
#[error(transparent)]
DecodeError(#[from] MessageDecodeError),
#[error("No handler was identified for key: '{key}'")]
NoHandler {
key: String,
},
#[error("Could not dispatch message: {0}")]
DispatchFailed(#[source] Box<dyn Error + Send + Sync>),
}
pub trait MessageHandler<M, E: Error>: Send + Sync + 'static
where
M: MessageBody,
E: Error,
{
fn handle(
&self,
connection: Connection,
msg: Message<M>,
) -> Result<(), E>;
#[inline]
fn is_valid(&self) -> bool { true }
}
impl<M, E, F> MessageHandler<M, E> for F
where
M: MessageBody,
E: Error,
F: (Fn(Connection, Message<M>) -> Result<(), E>) + Send + Sync + 'static,
{
#[inline]
fn handle(
&self,
connection: Connection,
msg: Message<M>,
) -> Result<(), E> {
self(connection, msg)
}
}
impl<M, E, H> MessageHandler<M, E> for Arc<H>
where
M: MessageBody,
E: Error,
H: MessageHandler<M, E>,
{
#[inline]
fn handle(&self, connection: Connection, msg: Message<M>) -> Result<(), E> {
(**self).handle(connection, msg)
}
}
impl<M, E, H> MessageHandler<M, E> for Weak<H>
where
M: MessageBody,
E: Error,
H: MessageHandler<M, E>,
{
#[inline]
fn handle(&self, connection: Connection, msg: Message<M>) -> Result<(), E> {
if let Some(handler) = self.upgrade() {
handler.handle(connection, msg)
} else {
Ok(())
}
}
#[inline]
fn is_valid(&self) -> bool {
if let Some(handler) = self.upgrade() {
handler.is_valid()
} else {
false
}
}
}