use std::collections::HashMap;
use models::*;
pub enum InsertRequestStatus {
Ok,
NoSuchBin,
}
pub enum DeleteBinStatus {
Ok,
NoSuchBin,
}
pub type Bin = Vec<Request>;
pub trait Bins {
fn create_bin(&mut self) -> BinSummary;
fn delete_bin(&mut self, id: &Id) -> DeleteBinStatus;
fn get_bin<'a>(&'a self, id: &'a Id) -> Option<&Bin>;
fn get_bin_summary(&self, id: &Id) -> Option<BinSummary>;
fn get_bin_summaries(&self) -> HashMap<Id, BinSummary>;
fn insert_request(&mut self, id: &Id, request: Request) -> InsertRequestStatus;
}
#[derive(Debug)]
pub struct InMemoryBins {
pub bins: HashMap<Id, Vec<Request>>,
}
impl InMemoryBins {
pub fn new() -> InMemoryBins {
InMemoryBins { bins: HashMap::new() }
}
}
impl Bins for InMemoryBins {
fn create_bin(&mut self) -> BinSummary {
let mut uuid = Id::random();
while self.bins.contains_key(&uuid) {
uuid = Id::random();
}
self.bins.insert(uuid.to_owned(), Vec::new());
BinSummary {
id: uuid,
request_count: 0,
}
}
fn delete_bin(&mut self, id: &Id) -> DeleteBinStatus {
match self.bins.remove(id) {
Some(_) => DeleteBinStatus::Ok,
_ => DeleteBinStatus::NoSuchBin,
}
}
fn get_bin_summary(&self, id: &Id) -> Option<BinSummary> {
self.bins.get(id).map(|b| {
BinSummary {
id: id.to_owned(),
request_count: b.len(),
}
})
}
fn get_bin_summaries(&self) -> HashMap<Id, BinSummary> {
let mut map: HashMap<Id, BinSummary> = HashMap::new();
for (k, b) in self.bins.iter() {
map.insert(
k.to_owned(),
BinSummary {
id: k.to_owned(),
request_count: b.len(),
},
);
}
map
}
fn get_bin(&self, id: &Id) -> Option<&Bin> {
self.bins.get(id)
}
fn insert_request(&mut self, id: &Id, request: Request) -> InsertRequestStatus {
match self.bins.get_mut(id) {
Some(bin) => {
bin.push(request);
InsertRequestStatus::Ok
}
None => InsertRequestStatus::NoSuchBin,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::HashMap;
#[test]
fn test_inmemory_bin_creation() {
let mut bins = InMemoryBins::new();
let _ = bins.create_bin();
}
#[test]
fn test_inmemory_bin_deletion() {
let mut bins = InMemoryBins::new();
let bin = bins.create_bin();
bins.delete_bin(&bin.id);
assert!(bins.bins.is_empty())
}
#[test]
fn test_inmemory_get_bin_summary() {
let mut bins = InMemoryBins::new();
let bin = bins.create_bin();
let req = Request {
content_length: None,
content_type: Some("fake".to_owned()),
time: 123,
method: "GET".to_owned(),
path: "/whoa".to_owned(),
body: None,
headers: HashMap::new(),
query_string: HashMap::new(),
};
bins.insert_request(&bin.id, req);
let summary = bins.get_bin_summary(&bin.id).unwrap();
assert_eq!(summary.request_count, 1)
}
#[test]
fn test_inmemory_get_bin() {
let mut bins = InMemoryBins::new();
let bin = bins.create_bin();
let req = Request {
content_length: None,
content_type: Some("fake".to_owned()),
time: 123,
method: "GET".to_owned(),
path: "/whoa".to_owned(),
body: None,
headers: HashMap::new(),
query_string: HashMap::new(),
};
bins.insert_request(&bin.id, req);
let summary = bins.get_bin(&bin.id).unwrap();
assert_eq!(
summary[0],
Request {
content_length: None,
content_type: Some("fake".to_owned()),
time: 123,
method: "GET".to_owned(),
path: "/whoa".to_owned(),
body: None,
headers: HashMap::new(),
query_string: HashMap::new(),
}
)
}
#[test]
fn test_inmemory_get_bin_summaries() {
let mut bins = InMemoryBins::new();
let bin = bins.create_bin();
let req = Request {
content_length: None,
content_type: Some("fake".to_owned()),
time: 123,
method: "GET".to_owned(),
path: "/whoa".to_owned(),
body: None,
headers: HashMap::new(),
query_string: HashMap::new(),
};
bins.insert_request(&bin.id, req);
let summaries = bins.get_bin_summaries();
assert_eq!(summaries.get(&bin.id).unwrap().request_count, 1)
}
}