use core::cmp::Ordering; use core::{mem, ptr}; use instant::Instant; #[doc(hidden)] #[repr(C)] pub struct Node where T: 'static, { baseline: Instant, payload: T, } impl Eq for Node {} impl Ord for Node { fn cmp(&self, rhs: &Self) -> Ordering { self.baseline.cmp(&rhs.baseline) } } impl PartialEq for Node { fn eq(&self, rhs: &Self) -> bool { self.baseline.eq(&rhs.baseline) } } impl PartialOrd for Node { fn partial_cmp(&self, rhs: &Self) -> Option { Some(self.cmp(rhs)) } } #[doc(hidden)] pub struct Slot where T: 'static, { node: &'static mut Node, } impl Slot { pub fn write(self, bl: Instant, data: T) -> Payload { self.node.baseline = bl; unsafe { ptr::write(&mut self.node.payload, data) } Payload { node: self.node } } } impl Into> for &'static mut Node { fn into(self) -> Slot { Slot { node: self } } } #[doc(hidden)] pub struct Payload where T: 'static, { node: &'static mut Node, } impl Payload { pub fn read(self) -> (Instant, T, Slot) { let data = unsafe { ptr::read(&self.node.payload) }; (self.node.baseline, data, Slot { node: self.node }) } pub fn tag(self, tag: A) -> TaggedPayload where A: Copy, { TaggedPayload { tag, payload: unsafe { mem::transmute(self) }, } } } #[doc(hidden)] pub struct TaggedPayload where A: Copy, { tag: A, payload: Payload, } impl TaggedPayload where A: Copy, { pub unsafe fn coerce(self) -> Payload { mem::transmute(self.payload) } pub fn baseline(&self) -> Instant { self.payload.node.baseline } pub fn tag(&self) -> A { self.tag } pub fn retag(self, tag: B) -> TaggedPayload where B: Copy, { TaggedPayload { tag, payload: self.payload, } } } impl Eq for TaggedPayload where T: Copy, { } impl Ord for TaggedPayload where T: Copy, { fn cmp(&self, rhs: &Self) -> Ordering { self.payload.node.cmp(&rhs.payload.node) } } impl PartialEq for TaggedPayload where T: Copy, { fn eq(&self, rhs: &Self) -> bool { self.payload.node.eq(&rhs.payload.node) } } impl PartialOrd for TaggedPayload where T: Copy, { fn partial_cmp(&self, rhs: &Self) -> Option { Some(self.cmp(rhs)) } }