Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AurevoirXavier/7cc791c4cd1599eb99760d070a58827f to your computer and use it in GitHub Desktop.
Save AurevoirXavier/7cc791c4cd1599eb99760d070a58827f to your computer and use it in GitHub Desktop.
[Rust] Objects with Reference to Self and Lifetime Subtyping
use std::collections::HashMap;
type Handler<'a> = Box<dyn Fn(i32) -> i32 + 'a>;
pub struct Router<'r> {
routes: HashMap<String, Handler<'r>>,
}
pub struct RouteAdder<'a, 'r: 'a> {
router: &'a mut Router<'r>,
route: String,
}
impl<'r> Router<'r> {
pub fn new() -> Self {
Router {
routes: HashMap::new(),
}
}
pub fn route<'a>(&'r mut self, route: String) -> RouteAdder<'a, 'r> {
RouteAdder::of(self, route)
}
pub fn send(&self, s: &str, x: i32) -> Option<i32> {
match self.routes.get(s) {
None => None,
Some(h) => Some(h(x)),
}
}
}
impl<'a, 'r> RouteAdder<'a, 'r> {
fn of(router: &'a mut Router<'r>, route: String) -> Self {
RouteAdder { router, route }
}
pub fn to(self, handler: impl Fn(i32) -> i32 + 'r) {
self.router.routes.insert(self.route, Box::new(handler));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_route() {
let router = {
let mut router = Router::new();
router.route(String::from("hello")).to(|x| x + 1);
router
};
assert_eq!(router.send("hello", 3), Some(4));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment