use num_traits::{FromPrimitive, One, Zero};
pub trait Stream<Itype> {
const SERIALIZER_ID: &'static str;
fn build(seed: Option<Itype>) -> Self;
fn set_stream(&mut self, _stream_seq: Itype) {
panic!("Stream setting unimplemented for this stream type");
}
fn increment(&self) -> Itype;
fn get_stream(&self) -> Itype;
}
pub struct OneSeqStream;
macro_rules! make_one_seq {
( $( $t:ty => $e:expr);* ) => {
$(impl Stream<$t> for OneSeqStream {
const SERIALIZER_ID: &'static str = "OneSeq";
fn build(_: Option<$t>) -> Self {
OneSeqStream
}
#[inline(always)]
fn increment(&self) -> $t {
$e
}
fn get_stream(&self) -> $t {
$e
}
})*
}
}
make_one_seq! {
u32 => 2_891_336_453u32;
u64 => 1_442_695_040_888_963_407u64;
u128 => 117_397_592_171_526_113_268_558_934_119_004_209_487u128 }
pub struct NoSeqStream;
macro_rules! make_no_seq {
( $( $t:ty => $e:expr);* ) => {
$(impl Stream<$t> for NoSeqStream {
const SERIALIZER_ID: &'static str = "NoSeq";
fn build(_: Option<$t>) -> Self {
NoSeqStream
}
#[inline(always)]
fn increment(&self) -> $t {
$e
}
fn get_stream(&self) -> $t {
$e
}
})*
}
}
make_no_seq! {
u32 => 0;
u64 => 0;
u128 => 0
}
pub struct SpecificSeqStream<Itype> {
inc: Itype,
}
impl<Itype> SpecificSeqStream<Itype>
where
Itype: Zero,
{
pub fn new() -> SpecificSeqStream<Itype> {
SpecificSeqStream { inc: Itype::zero() }
}
}
macro_rules! make_set_seq {
( $( $t:ident => $e:expr);* ) => {
$(impl Stream<$t> for SpecificSeqStream<$t> {
const SERIALIZER_ID: &'static str = "SetSeq";
fn build(seed: Option<$t>) -> Self {
match seed {
None => SpecificSeqStream {
inc : $e,
},
Some(seed) => SpecificSeqStream {
inc: seed | $t::one(),
},
}
}
fn set_stream(&mut self, stream_seq : $t) {
self.inc = stream_seq | $t::one();
}
#[inline(always)]
fn increment(&self) -> $t {
self.inc
}
fn get_stream(&self) -> $t {
self.inc
}
})*
}
}
make_set_seq! {
u32 => 2_891_336_453u32;
u64 => 1_442_695_040_888_963_407u64;
u128 => 117_397_592_171_526_113_268_558_934_119_004_209_487u128 }
pub struct UniqueSeqStream;
impl<Itype> Stream<Itype> for UniqueSeqStream
where
Itype: FromPrimitive + ::seeds::ReadByteOrder,
{
const SERIALIZER_ID: &'static str = "Uniq";
fn build(_: Option<Itype>) -> Self {
UniqueSeqStream
}
#[inline(always)]
fn increment(&self) -> Itype {
Itype::from_usize(self as *const UniqueSeqStream as usize | 1).unwrap()
}
fn get_stream(&self) -> Itype {
Itype::from_usize(self as *const UniqueSeqStream as usize | 1).unwrap()
}
}