aboutsummaryrefslogtreecommitdiff
path: root/src/uid.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/uid.rs')
-rw-r--r--src/uid.rs90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/uid.rs b/src/uid.rs
new file mode 100644
index 0000000..b15f65b
--- /dev/null
+++ b/src/uid.rs
@@ -0,0 +1,90 @@
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
+pub struct UID(u8, u8);
+impl UID {
+ fn to_hex(&self) -> String {
+ hex::encode_upper(vec![self.0, self.1])
+ }
+ pub fn from(s: String) -> Result<Self, String> {
+ if s.is_ascii() {
+ if s.len() == 4 {
+ match hex::decode(s) {
+ Ok(n) => Ok(UID(n[0], n[1])),
+ Err(_) => Err("Could not decode hex".into())
+ }
+
+ } else {
+ Err("UID length is incorrect".into())
+ }
+ } else {
+ Err("UID String is not valid".into())
+ }
+ }
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct Generator {
+ used_uids: Vec<UID>
+}
+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<UID, String> {
+ if self.used_uids.contains(&u) {
+ Err("UID Taken".into())
+ } else {
+ self.used_uids.push(u);
+ Ok(u)
+ }
+ }
+
+ pub fn new_uid(&mut self) -> Result<UID, String> {
+ let mut count = 0;
+ loop {
+ let first = rand::random::<u8>();
+ let second = rand::random::<u8>();
+ 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())
+ }
+} \ No newline at end of file