#![cfg_attr(any(feature = "no_std",features = "alloc"), no_std)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::string::String;
#[cfg(not(any(feature = "no_std",features = "alloc")))]
extern crate std as core;
#[cfg(not(any(feature = "no_std",features = "alloc")))]
extern crate base32;
#[cfg(test)]
mod tests;
#[derive(Clone,Eq,Debug)]
pub struct Guuid{
time: u64,
random : u64
}
impl PartialEq for Guuid {
fn eq(&self, other: &Self) -> bool {
self.time == other.time
&&
self.random == other.random
}
}
impl Guuid{
pub fn as_u128(&self) -> u128 {
let mut result = self.time as u128;
result = (result << 64) + (self.random as u128);
result
}
pub fn time(&self) -> u64 {
self.time
}
pub fn random(&self) -> u64 {
self.random
}
pub fn new(time: u64, random: u64) -> Guuid{
Guuid{
time: time,
random: random
}
}
pub fn from_u128(u128: u128) -> Guuid {
Guuid{
time: (u128 >> 64) as u64,
random: u128 as u64
}
}
#[cfg(not(feature = "no_std"))]
pub fn from_string(str: &str) -> Option<Guuid> {
use base32::decode;
use core::convert::TryInto;
match decode(base32::Alphabet::Crockford, str){
Some(ok) => Some(Guuid::from_bytes(ok.try_into().unwrap())),
None => None
}
}
#[cfg(not(feature = "no_std"))]
pub fn to_string(&self) -> String {
use base32::encode;
encode(base32::Alphabet::Crockford, &self.to_bytes())
}
#[cfg(feature = "std")]
pub fn gen_guuid_from_time(time : u64) -> Guuid{
use rand::RngCore;
let random = rand::rngs::OsRng.next_u64();
Guuid::new(time,random)
}
#[cfg(feature = "std")]
pub fn gen_guuid() -> Result<Guuid,std::time::SystemTimeError>{
use core::convert::TryInto;
match std::time::SystemTime::now().duration_since(std::time::SystemTime::UNIX_EPOCH) {
Ok(n) => Ok(Guuid::gen_guuid_from_time(n.as_millis().try_into().unwrap())),
Err(err) => Err(err),
}
}
pub fn to_bytes(&self) -> [u8;16]{
self.as_u128().to_be_bytes()
}
pub fn from_bytes(bytes: [u8;16]) -> Guuid {
Guuid::from_u128(u128::from_be_bytes(bytes))
}
}