use base16ct::lower; use rocket::request::FromParam; use serde::{de::{IntoDeserializer, Visitor}, Deserialize, Deserializer, Serialize}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct UID(u8, u8); struct UIDVisitor; impl<'de> Visitor<'de> for UIDVisitor { type Value = UID; fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { formatter.write_str("A Hex String containing 2 bytes") } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { if v.is_ascii() { if v.len() == 4 { match hex::decode(v) { Ok(n) => Ok(UID(n[0], n[1])), Err(_) => Err(serde::de::Error::custom("Could not decode hex")) } } else { Err(serde::de::Error::custom("ID must be a 2 byte hex string \'0000\'-\"FFFF\"")) } } else { Err(serde::de::Error::custom("Invalid characters in string")) } } } impl<'de> Deserialize<'de> for UID { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_str(UIDVisitor) } } impl From<&str> for UID { fn from(value: &str) -> Self { if value.is_ascii() { if value.len() == 4 { match hex::decode(value) { Ok(n) => UID(n[0], n[1]), Err(_) => panic!("Could not decode hex") } } else { panic!(); } } else { panic!(); } } } impl Serialize for UID { fn serialize(&self, serializer: S) -> Result where S: serde::Serializer { serializer.serialize_str(&lower::encode_string(&[self.0, self.1])) } } impl<'a> FromParam<'a> for UID { type Error = &'a str; fn from_param(param: &'a str) -> Result { let x: Result = param.into_deserializer().deserialize_str(UIDVisitor); match x { Ok(n) => Ok(n), Err(_) => Err("Could not convert param using deserializer"), } } } #[derive(Serialize, Deserialize)] pub struct Generator { used_uids: Vec } impl Generator { pub fn new() -> Generator { Generator { used_uids: vec![] } } pub fn is_taken(&self, uid: UID) -> bool { for u in self.used_uids.clone() { if u == uid { return true; } } false } pub fn add_uid(&mut self, u: UID) -> Result { if self.used_uids.contains(&u) { Err("UID Taken".into()) } else { self.used_uids.push(u); Ok(u) } } pub fn delete_uid(&mut self, u: UID) { self.used_uids = self.used_uids.clone().into_iter().filter(|old| old != &u).collect(); } pub fn new_uid(&mut self) -> Result { let mut count = 0; loop { let first = rand::random::(); let second = rand::random::(); let new = UID(first, second); if self.used_uids.contains(&new) { count += 1 } else { self.used_uids.push(new); return Ok(new); } if count > 1000 { break } } // Random generation didn't work. Try counting up throught all UID possibilities loop { for x in 0..=u8::MAX { for y in 0..=u8::MAX { let new = UID(x, y); if !(self.used_uids.contains(&new)) { self.used_uids.push(new); return Ok(new); } } } break } Err("No available UID left".into()) } }