use std::mem::size_of;
use std::intrinsics::TypeId;
use rawmessage::RawMessage;
use syncmessage::SyncMessage;
pub fn workaround_to_static_bug() {
panic!("sync message was not correct type");
}
pub struct Message {
pub srcsid: u64, pub srceid: u64, pub dstsid: u64, pub dsteid: u64, pub payload: MessagePayload, }
pub struct CloneMessage {
pub hash: u64,
pub payload: RawMessage,
}
pub enum MessagePayload {
Raw(RawMessage),
Sync(SyncMessage),
Clone(CloneMessage),
}
impl Clone for Message {
fn clone(&self) -> Message {
match self.payload {
MessagePayload::Raw(ref msg) => {
Message {
srcsid: self.srcsid, srceid: self.srceid,
dstsid: self.dstsid, dsteid: self.dsteid,
payload: MessagePayload::Raw((*msg).clone())
}
},
MessagePayload::Clone(ref msg) => {
Message {
srcsid: self.srcsid, srceid: self.srceid,
dstsid: self.dstsid, dsteid: self.dsteid,
payload: MessagePayload::Clone((*msg).clone())
}
}
MessagePayload::Sync(ref msg) => {
panic!("Tried to clone a SyncMessage which is unique!");
}
}
}
}
impl Message {
pub fn cap(&self) -> uint {
match self.payload {
MessagePayload::Raw(ref msg) => msg.cap(),
MessagePayload::Sync(ref msg) => msg.payload.cap(),
MessagePayload::Clone(ref msg) => msg.payload.cap(),
}
}
pub fn dup(&self) -> Message {
match self.payload {
MessagePayload::Raw(ref msg) => {
Message {
dstsid: self.dstsid, dsteid: self.dsteid,
srcsid: self.srcsid, srceid: self.srceid,
payload: MessagePayload::Raw(msg.clone())
}
},
_ => {
panic!("message type can not be duplicated!");
}
}
}
pub fn get_raw(self) -> RawMessage {
match self.payload {
MessagePayload::Raw(msg) => {
msg
},
_ => {
panic!("message was not type raw! [consider checking type]")
}
}
}
pub fn get_rawref(&mut self) -> &mut RawMessage {
match self.payload {
MessagePayload::Raw(ref mut msg) => {
msg
},
_ => {
panic!("message was not type raw! [consider checking type]")
}
}
}
pub fn get_sync(self) -> SyncMessage {
match self.payload {
MessagePayload::Sync(msg) => {
msg
},
_ => {
panic!("message was not type sync! [consider checking type]")
}
}
}
pub fn is_clone(&self) -> bool {
match self.payload {
MessagePayload::Sync(_) => false,
MessagePayload::Raw(_) => false,
MessagePayload::Clone(_) => true,
}
}
pub fn is_raw(&self) -> bool {
match self.payload {
MessagePayload::Sync(_) => false,
MessagePayload::Raw(_) => true,
MessagePayload::Clone(_) => false,
}
}
pub fn is_sync(&self) -> bool {
match self.payload {
MessagePayload::Sync(_) => true,
MessagePayload::Raw(_) => false,
MessagePayload::Clone(_) => false,
}
}
pub fn new_raw(cap: uint) -> Message {
Message {
srcsid: 0, srceid: 0,
dstsid: 0, dsteid: 0,
payload: MessagePayload::Raw(RawMessage::new(cap))
}
}
pub fn new_clone<T: Send + Clone + 'static>(t: T) -> Message {
let payload = MessagePayload::Clone(CloneMessage::new(t));
Message {
srcsid: 0, srceid: 0, dstsid: 0, dsteid: 0,
payload: payload,
}
}
pub fn new_sync<T: Send + 'static>(t: T) -> Message {
let payload = MessagePayload::Sync(SyncMessage::new(t));
Message {
srcsid: 0, srceid: 0, dstsid: 0, dsteid: 0,
payload: payload,
}
}
}
impl Clone for CloneMessage {
fn clone(&self) -> CloneMessage {
CloneMessage {
hash: self.hash,
payload: self.payload.clone(),
}
}
}
impl CloneMessage {
pub fn new<T: Send + Clone + 'static>(t: T) -> CloneMessage {
let tyid = TypeId::of::<T>();
let hash = tyid.hash();
let mut rmsg = RawMessage::new(size_of::<T>());
rmsg.writestruct(0, t);
CloneMessage {
hash: hash,
payload: rmsg
}
}
pub fn get_payload<T: Send + Clone + 'static>(self) -> T {
let rawmsg = self.payload;
let tyid = TypeId::of::<T>();
let hash = tyid.hash();
if hash != self.hash {
panic!("clone message was not correct type");
}
let t: T = unsafe { rawmsg.readstructunsafe(0) };
t
}
}