diff --git a/Cargo.lock b/Cargo.lock index 71d70e1..1994bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,3 +5,12 @@ version = 3 [[package]] name = "icechip" version = "0.1.0" +dependencies = [ + "tinyrand", +] + +[[package]] +name = "tinyrand" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ffaad2263779579369d45f65cad0647c860893d27e4543cdcc1e428d07da2c" diff --git a/Cargo.toml b/Cargo.toml index 665680c..738d3e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,3 +6,4 @@ repository = "https://git.cbax.dev/icechip" license = "MIT OR Apache-2.0" [dependencies] +tinyrand = "0.5.0" diff --git a/src/lib.rs b/src/lib.rs index ed05f5c..d552b3c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +use tinyrand::{Rand, StdRand}; + use std::time::{SystemTime, UNIX_EPOCH}; #[derive(Clone, Debug)] @@ -6,7 +8,7 @@ pub enum Version { EXTENDED, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct Icechip { version: Version, timestamp: T, @@ -69,22 +71,44 @@ impl From for Icechip { } } -impl Icechip { +impl Icechip { pub fn set_epoch(mut self, epoch: u128) { self.epoch = Some(epoch); } + + pub fn timestamp(&self) -> T { + return self.timestamp.clone(); + } + + pub fn machine_id(&self) -> T { + return self.machine_id.clone(); + } + + pub fn sequence_id(&self) -> T { + return self.sequence_id.clone(); + } + + pub fn version(&self) -> Version { + return self.version.clone(); + } } impl Icechip { - pub fn new(version: Version, epoch: Option) -> Icechip { - todo!(); - } - - fn offset_epoch(&self, timestamp: u128) -> u64 { - match self.epoch { - Some(s) => return (timestamp - s) as u64, - None => return timestamp as u64, + pub fn new(epoch: Option) -> Icechip { + let mut rand = StdRand::default(); + return Icechip { + version: Version::ENHANCED, + timestamp: 0, + machine_id: rand + .next_u64() + .checked_shl(41) + .unwrap() + .checked_shr(53) + .unwrap(), + sequence_id: 0, + epoch, } + .tick(); } pub fn tick(&self) -> Icechip { @@ -92,10 +116,10 @@ impl Icechip { Ok(o) => { let o = o.as_millis(); let curr_ts = match self.epoch { - Some(s) => (o - s).checked_shl(23).unwrap().checked_shr(23).unwrap(), - None => o.checked_shl(23).unwrap().checked_shr(23).unwrap(), + Some(s) => (o - s).checked_shl(23).unwrap().checked_shr(23).unwrap() as u64, + None => o.checked_shl(23).unwrap().checked_shr(23).unwrap() as u64, }; - if self.timestamp as u128 == curr_ts { + if self.timestamp == curr_ts { if (self.sequence_id + 1) > 1023 { std::thread::sleep(std::time::Duration::from_millis(1)); return self.tick(); @@ -111,7 +135,7 @@ impl Icechip { } else { return Icechip { version: self.version.clone(), - timestamp: self.offset_epoch(curr_ts.clone()), + timestamp: curr_ts.clone(), machine_id: self.machine_id.clone(), sequence_id: 0, epoch: self.epoch.clone(), @@ -125,22 +149,33 @@ impl Icechip { } } - pub fn with_id(machine_id: u32, version: Version) -> Icechip { - todo!(); - /*match version { - Version::ENHANCED => { + pub fn with_id(machine_id: u64, epoch: Option) -> Icechip { + return Icechip { + version: Version::ENHANCED, + timestamp: 0, + machine_id, + sequence_id: 0, + epoch, + } + .tick(); + } - }, - Version::EXTENDED => { - - } - }*/ + pub fn to_u64(self) -> u64 { + return Into::::into(self); } } impl Icechip { - pub fn new(version: Version, epoch: Option) -> Icechip { - todo!(); + pub fn new(epoch: Option) -> Icechip { + let mut rand = StdRand::default(); + return Icechip { + version: Version::EXTENDED, + timestamp: 0, + machine_id: rand.next_u128(), + sequence_id: 0, + epoch, + } + .tick(); } pub fn tick(&self) -> Icechip { @@ -181,16 +216,19 @@ impl Icechip { } } - pub fn with_id(machine_id: u32, version: Version) -> Icechip { - todo!(); - /*match version { - Version::ENHANCED => { + pub fn with_id(machine_id: u128, epoch: Option) -> Icechip { + return Icechip { + version: Version::EXTENDED, + timestamp: 0, + machine_id, + sequence_id: 0, + epoch, + } + .tick(); + } - }, - Version::EXTENDED => { - - } - }*/ + pub fn to_u128(self) -> u128 { + return Into::::into(self); } } @@ -200,13 +238,45 @@ mod tests { #[test] fn from_into_u128() { - let test_chip = Icechip::from(0x0123456789ABCDEFu128); - assert_eq!(0x0123456789ABCDEFu128, test_chip.into()); + let test_chip = Icechip::from(1234567890u128); + assert_eq!(1234567890u128, test_chip.into()); } #[test] fn from_into_u64() { - let test_chip = Icechip::from(0x0123456789ABCDEFu64); - assert_eq!(0x0123456789ABCDEFu64, test_chip.into()); + let test_chip = Icechip::from(1234567890u64); + assert_eq!(1234567890u64, test_chip.into()); + } + + #[test] + fn custom_machine_id_u128() { + let test_chip = Icechip::::with_id(1u128, None); + test_chip.tick(); + assert_eq!(test_chip.machine_id(), 1u128); + } + + #[test] + fn custom_machine_id_u64() { + let test_chip = Icechip::::with_id(1u64, None); + test_chip.tick(); + assert_eq!(test_chip.machine_id(), 1u64); + } + + #[test] + fn tick_u128() { + let test_chip = Icechip::::new(None); + println!("test: {:#b}", test_chip.clone().to_u128()); + let ticked_chip = test_chip.tick(); + println!("tick: {:#b}", ticked_chip.clone().to_u128()); + assert!(test_chip.clone().to_u128() < ticked_chip.to_u128()); + } + + #[test] + fn tick_u64() { + let test_chip = Icechip::::new(None); + println!("test: {:#b}", test_chip.clone().to_u64()); + let ticked_chip = test_chip.tick(); + println!("tick: {:#b}", ticked_chip.clone().to_u64()); + assert!(test_chip.clone().to_u64() < ticked_chip.to_u64()); } }