Added random id generator.
This commit is contained in:
		@@ -1,9 +1,78 @@
 | 
			
		||||
use super::{ErrorCode, FromCache, MTTError, Store, ToCache, ENTRY};
 | 
			
		||||
use async_std::{channel::Receiver, path::PathBuf};
 | 
			
		||||
use std::collections::HashMap;
 | 
			
		||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
 | 
			
		||||
use std::{collections::{HashMap, VecDeque}, iter::Iterator};
 | 
			
		||||
 | 
			
		||||
struct IDGenerator {
 | 
			
		||||
    ids: Option<VecDeque<String>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl IDGenerator {
 | 
			
		||||
    fn new() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            ids: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn with_ids<T, D>(ids: T) -> Self where T: Into<Vec<D>>, D: Into<String> {
 | 
			
		||||
        let id_list = ids.into();
 | 
			
		||||
        let mut data = VecDeque::new();
 | 
			
		||||
        for id in id_list {
 | 
			
		||||
            data.push_back(id.into());
 | 
			
		||||
        }
 | 
			
		||||
        Self {
 | 
			
		||||
            ids: Some(data),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Iterator for IDGenerator {
 | 
			
		||||
    type Item = String;
 | 
			
		||||
 | 
			
		||||
    fn next(&mut self) -> Option<Self::Item> {
 | 
			
		||||
        match &self.ids {
 | 
			
		||||
            Some(id_list) => {
 | 
			
		||||
                let mut ids = id_list.clone();
 | 
			
		||||
                let output = match ids.pop_front() {
 | 
			
		||||
                    Some(id) => Some(id.to_string()),
 | 
			
		||||
                    None => None,
 | 
			
		||||
                };
 | 
			
		||||
                self.ids = Some(ids);
 | 
			
		||||
                output
 | 
			
		||||
            }
 | 
			
		||||
            None => Some(thread_rng().sample_iter(&Alphanumeric).take(64).collect()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[cfg(test)]
 | 
			
		||||
mod genid {
 | 
			
		||||
    use super::*;
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn unique_ids() {
 | 
			
		||||
        let mut gen = IDGenerator::new();
 | 
			
		||||
        let mut output: Vec<String> = Vec::new();
 | 
			
		||||
        for _ in 0..10 {
 | 
			
		||||
            let id = gen.next().unwrap();
 | 
			
		||||
            assert!(!output.contains(&id), "{} found in {:?}", id, output);
 | 
			
		||||
            output.push(id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[test]
 | 
			
		||||
    fn controlled_ids() {
 | 
			
		||||
        let ids = ["one",  "two", "three"];
 | 
			
		||||
        let mut gen = IDGenerator::with_ids(ids.clone());
 | 
			
		||||
        for id in ids {
 | 
			
		||||
            assert_eq!(id, gen.next().unwrap());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub struct Cache {
 | 
			
		||||
    data: HashMap<String, Store>,
 | 
			
		||||
    ids: IDGenerator,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Cache {
 | 
			
		||||
@@ -13,7 +82,10 @@ impl Cache {
 | 
			
		||||
    {
 | 
			
		||||
        let mut data = HashMap::new();
 | 
			
		||||
        data.insert(ENTRY.to_string(), Store::new());
 | 
			
		||||
        Self { data: data }
 | 
			
		||||
        Self { 
 | 
			
		||||
            data: data,
 | 
			
		||||
            ids: IDGenerator::new(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub async fn listen(&mut self, listener: Receiver<ToCache>) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user