timely_communication/
message.rsuse std::sync::Arc;
use bytes::arc::Bytes;
use crate::Data;
pub enum RefOrMut<'a, T> where T: 'a {
Ref(&'a T),
Mut(&'a mut T),
}
impl<'a, T: 'a> ::std::ops::Deref for RefOrMut<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match self {
RefOrMut::Ref(reference) => reference,
RefOrMut::Mut(reference) => reference,
}
}
}
impl<'a, T: 'a> ::std::borrow::Borrow<T> for RefOrMut<'a, T> {
fn borrow(&self) -> &T {
match self {
RefOrMut::Ref(reference) => reference,
RefOrMut::Mut(reference) => reference,
}
}
}
impl<'a, T: Clone+'a> RefOrMut<'a, T> {
pub fn swap<'b>(self, element: &'b mut T) {
match self {
RefOrMut::Ref(reference) => element.clone_from(reference),
RefOrMut::Mut(reference) => ::std::mem::swap(reference, element),
};
}
pub fn replace(self, mut element: T) -> T {
self.swap(&mut element);
element
}
pub fn take(self) -> T where T: Default {
let mut element = Default::default();
self.swap(&mut element);
element
}
}
pub struct Message<T> {
payload: MessageContents<T>,
}
enum MessageContents<T> {
Owned(T),
Arc(Arc<T>),
}
impl<T> Message<T> {
pub fn from_typed(typed: T) -> Self {
Message { payload: MessageContents::Owned(typed) }
}
pub fn from_arc(typed: Arc<T>) -> Self {
Message { payload: MessageContents::Arc(typed) }
}
pub fn if_typed(self) -> Option<T> {
match self.payload {
MessageContents::Owned(typed) => Some(typed),
MessageContents::Arc(_) => None,
}
}
pub fn if_mut(&mut self) -> Option<&mut T> {
match &mut self.payload {
MessageContents::Owned(typed) => Some(typed),
MessageContents::Arc(_) => None,
}
}
pub fn as_ref_or_mut(&mut self) -> RefOrMut<T> {
match &mut self.payload {
MessageContents::Owned(typed) => { RefOrMut::Mut(typed) },
MessageContents::Arc(typed) => { RefOrMut::Ref(typed) },
}
}
}
impl<T: Data> Message<T> {
pub fn from_bytes(bytes: Bytes) -> Self {
let typed = ::bincode::deserialize(&bytes[..]).expect("bincode::deserialize() failed");
Message { payload: MessageContents::Owned(typed) }
}
pub fn length_in_bytes(&self) -> usize {
match &self.payload {
MessageContents::Owned(typed) => {
::bincode::serialized_size(&typed).expect("bincode::serialized_size() failed") as usize
},
MessageContents::Arc(typed) => {
::bincode::serialized_size(&**typed).expect("bincode::serialized_size() failed") as usize
},
}
}
pub fn into_bytes<W: ::std::io::Write>(&self, writer: &mut W) {
match &self.payload {
MessageContents::Owned(typed) => {
::bincode::serialize_into(writer, &typed).expect("bincode::serialize_into() failed");
},
MessageContents::Arc(typed) => {
::bincode::serialize_into(writer, &**typed).expect("bincode::serialize_into() failed");
},
}
}
}
impl<T> ::std::ops::Deref for Message<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match &self.payload {
MessageContents::Owned(typed) => { typed },
MessageContents::Arc(typed) => { typed },
}
}
}
impl<T: Clone> Message<T> {
pub fn into_typed(self) -> T {
match self.payload {
MessageContents::Owned(instance) => instance,
MessageContents::Arc(instance) => (*instance).clone(),
}
}
pub fn as_mut(&mut self) -> &mut T {
let cloned: Option<T> = match &self.payload {
MessageContents::Owned(_) => None,
MessageContents::Arc(typed) => Some((**typed).clone()),
};
if let Some(cloned) = cloned {
self.payload = MessageContents::Owned(cloned);
}
if let MessageContents::Owned(typed) = &mut self.payload {
typed
}
else {
unreachable!()
}
}
}