use std::collections::HashMap;
use std::fmt;
use uuid::Uuid;
use regex::Regex;
const ID_REGEXP: &'static str =
r"^((?i)[A-F0-9]{8}\-[A-F0-9]{4}\-4[A-F0-9]{3}\-[89AB][A-F0-9]{3}\-[A-F0-9]{12})$";
#[derive(PartialEq, Debug, Eq, Hash, Clone, Serialize, Deserialize)]
pub struct Id(String);
impl Id {
pub fn random() -> Id {
Id(Uuid::new_v4().to_string())
}
pub fn value(&self) -> &str {
&*self.0
}
}
pub struct IdExtractor(Regex);
impl IdExtractor {
pub fn new() -> IdExtractor {
match Regex::new(ID_REGEXP) {
Ok(regex) => IdExtractor(regex),
_ => unreachable!(), }
}
pub fn parse(&self, s: &str) -> Option<Id> {
let caps = self.0.captures(s);
caps.and_then(|c| c.get(1).map(|r| Id(r.as_str().to_owned())))
}
}
impl fmt::Display for Id {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(PartialEq, Debug, Eq, Serialize, Deserialize)]
pub struct Request {
pub content_length: Option<u64>,
pub content_type: Option<String>,
pub time: i64,
pub method: String,
pub path: String,
pub body: Option<String>,
pub headers: HashMap<String, Vec<String>>,
pub query_string: HashMap<String, Vec<String>>,
}
#[derive(PartialEq, Debug, Eq, Serialize, Deserialize)]
pub struct BinSummary {
pub id: Id,
pub request_count: usize,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json;
#[test]
fn test_idextractor_instantiation() {
let _ = IdExtractor::new();
}
#[test]
fn test_id_json_encoding_decoding() {
let id = Id::random();
let encoded = serde_json::to_string_pretty(&id).unwrap();
let decoded: Id = serde_json::from_str(&*encoded).unwrap();
assert_eq!(decoded, id);
assert_eq!(format!("\"{}\"", id), encoded); }
}