Skip to main content

minimal_id/
seed.rs

1use byteorder::{NetworkEndian, WriteBytesExt};
2use std::time::SystemTime;
3
4/// Type representing the seed value
5#[derive(Debug, PartialEq, Eq, Ord, PartialOrd)]
6pub struct Seed {
7	value: u32,
8}
9
10impl Seed {
11	/// Creates a new seed with a specific value
12	pub fn new(value: u32) -> Self { Self { value } }
13
14	/// Creates a new seed based on the current time
15	///
16	/// ```
17	/// # use minimal_id::Seed;
18	/// let seed = Seed::from_time();
19	/// println!("Seed = {:?}", seed);
20	/// ```
21	pub fn from_time() -> Self {
22		let year_start = SystemTime::UNIX_EPOCH;
23		Self {
24			value: get_seconds_since(year_start),
25		}
26	}
27
28	/// Returns the seed as a byte array in Network endian
29	///
30	/// This does make copies of the data, but since it's only 4 bytes
31	/// we think it's an okay trade off.
32	pub fn as_slice(&self) -> [u8; 4] {
33		let mut data = vec![];
34		data.write_u32::<NetworkEndian>(self.value).expect("Cannot write seed");
35
36		let mut array = [0; 4];
37		array.copy_from_slice(&data[..4]);
38		array
39	}
40}
41
42fn get_seconds_since(anchor: SystemTime) -> u32 {
43	let duration = SystemTime::now()
44		.duration_since(anchor)
45		.expect("Unable to calculate duration");
46	duration.as_secs() as u32
47}
48
49#[cfg(test)]
50mod tests {
51	use super::*;
52
53	#[test]
54	fn functional_seed_to_slice() {
55		let seed = Seed::new(10 << 24 | 20 << 16 | 30 << 8 | 40);
56		let slc = seed.as_slice();
57		assert_eq!(slc.get(0), Some(&10));
58		assert_eq!(slc.get(1), Some(&20));
59		assert_eq!(slc.get(2), Some(&30));
60		assert_eq!(slc.get(3), Some(&40));
61	}
62}