use std::collections::HashMap;
use std::sync::{Arc, RwLock};
#[derive(Clone)]
pub struct Router<T: Clone> {
r: matchit::Router<T>,
}
impl<T: Clone> Router<T> {
pub fn new() -> Self {
Self {
r: matchit::Router::new(),
}
}
pub fn insert(&mut self, path: &str, v: T) -> Result<Option<T>, ()> {
let old = self.r.remove(path);
match self.r.insert(path, v.clone()) {
Ok(_) => Ok(old),
Err(_) => Err(()),
}
}
pub fn remove(&mut self, path: &str) -> Option<T> {
self.r.remove(path)
}
pub fn at(&self, path: &str) -> Option<&T> {
match self.r.at(path) {
Err(_) => None,
Ok(m) => Some(m.value),
}
}
pub fn at_with_params<'a>(
&'a self,
path: &'a str,
) -> Option<(&'a T, HashMap<&'a str, &'a str>)> {
match self.r.at(path) {
Err(_) => None,
Ok(m) => {
let mut p = HashMap::new();
for (k, v) in m.params.iter() {
p.insert(k, v);
}
Some((m.value, p))
}
}
}
}
#[derive(Clone)]
pub struct ARouter<T: Clone> {
r: Arc<RwLock<Router<T>>>,
}
impl<T: Clone> ARouter<T> {
pub fn new() -> Self {
Self {
r: Arc::new(RwLock::new(Router::new())),
}
}
pub fn insert(&self, path: &str, v: T) -> Result<Option<T>, ()> {
let mut wg = self.r.write().unwrap();
wg.insert(path, v)
}
pub fn remove(&mut self, path: &str) -> Option<T> {
let mut wg = self.r.write().unwrap();
wg.remove(path)
}
pub fn at(&self, path: &str) -> Option<T> {
let g = self.r.read().unwrap();
g.at(path).map(|v| v.clone())
}
pub fn at_with_params(&self, path: &str) -> Option<(T, HashMap<String, String>)> {
let g = self.r.read().unwrap();
g.at_with_params(path).map(|i| {
(
i.0.clone(),
i.1.iter()
.map(|kv| (kv.0.to_string(), kv.1.to_string()))
.collect(),
)
})
}
}
#[test]
fn test_router() {
let mut r = ARouter::new(); let mut r2 = r.clone();
println!("{:?}", r.insert("/{service}/{method}", "http"));
println!("{:?}", r.insert("/{service}/{method}", "http request"));
println!("{:?}", r.at("/game/send"));
println!("{:?}", r.at_with_params("/game/send"));
println!("{:?}", r2.remove("/{service}/{method}"));
println!("{:?}", r.at("/game/send"));
println!("{:?}", r.remove("/{service}/{method}"));
}