I'm creating a relatively simple type-safe and thread-safe Rust event system. It is to be used with and within an IRC library I'm making, but should work just fine for other use-cases. It needs to be reasonably good and safe. Using it might require lazy-static, which makes me slightly worried, but even then it should be safe.This is the event.rs code:use std::collections::HashMap;use std::marker::PhantomData;extern crate uuid;use self::uuid::Uuid;// Note: This doesn't support Copy or Clone for safety reasons.// More specifically, it should be impossible to unregister the same handler more than once.pub struct EventHandlerId<T: Event + ?Sized> {  id: Uuid,  _t: PhantomData<T>,}impl<T: Event + ?Sized> Eq for EventHandlerId<T> {}impl<T: Event + ?Sized> PartialEq for EventHandlerId<T> {  fn eq(&self, other: &Self) -> bool {    self.id == other.id && self._t == other._t  }}struct EventHandler<T: Event + ?Sized> {  priority: i32,  f: fn(&mut T),  id: EventHandlerId<T>,}pub struct EventMetadata<T: Event + ?Sized> {  handlers: HashMap<&'static EventBus, Vec<EventHandler<T>>>,}impl<T: Event + ?Sized> EventMetadata<T> {  pub fn new() -> EventMetadata<T> {    EventMetadata { handlers: HashMap::new() }  }  fn put(&mut self, bus: &'static EventBus, f: fn(&mut T), priority: i32) -> EventHandlerId<T> {    let vec = self.handlers.entry(bus).or_insert_with(Vec::new);    let pos = vec.binary_search_by(|a| a.priority.cmp(&priority)).unwrap_or_else(|e| e);    let id = Uuid::new_v4();    vec.insert(pos, EventHandler { f: f, priority: priority, id: EventHandlerId { id: id, _t: PhantomData } });    EventHandlerId { id: id, _t: PhantomData }  }  fn remove(&mut self, bus: &EventBus, f: EventHandlerId<T>) {    let flag = self.handlers.get_mut(bus).iter_mut().any(|v| { v.retain(|x| x.id != f); v.is_empty() });    if flag { self.handlers.remove(bus); }  }  #[inline]  fn post(&self, bus: &EventBus, event: &mut T) -> bool {    self.handlers.get(bus).iter().flat_map(|x| x.iter()).any(|h| {      (h.f)(event);      event.cancelled()    })  }}pub trait Event {  // type properties  fn event_metadata<F, R>(F) -> R where F: FnOnce(&EventMetadata<Self>) -> R;  fn mut_metadata<F, R>(F) -> R where F: FnOnce(&mut EventMetadata<Self>) -> R;  fn cancellable() -> bool { false }  // instance properties  fn cancelled(&self) -> bool { false }  fn cancel(&self, bool) { panic!() }}#[derive(PartialEq, Eq, Hash)]pub struct EventBus {  uuid: Uuid}impl EventBus { pub fn new() -> EventBus {   EventBus { uuid: Uuid::new_v4() } } pub fn register<T>(&'static self, f: fn(&mut T), priority: i32) -> EventHandlerId<T> where T: Event {   T::mut_metadata(|x| x.put(self, f, priority)) } pub fn unregister<T>(&self, f: EventHandlerId<T>) where T: Event {   T::mut_metadata(|x| x.remove(self, f)) } pub fn post<T>(&self, event: &mut T) -> bool where T: Event {   T::event_metadata(|x| x.post(self, event)) }}It is to be used like this: (main.rs)mod event;use event::{EventBus, EventMetadata, Event};use std::sync::RwLock;#[macro_use]extern crate lazy_static;struct NoEvent {  i: i32}lazy_static! {  static ref NOEVENT_METADATA: RwLock<EventMetadata<NoEvent>> = RwLock::new(EventMetadata::new());  static ref EVENT_BUS: EventBus = EventBus::new();}impl Event for NoEvent {  fn event_metadata<F, R>(f: F) -> R where F: FnOnce(&EventMetadata<Self>) -> R {    f(&*NOEVENT_METADATA.read().unwrap())  }  fn mut_metadata<F, R>(f: F) -> R where F: FnOnce(&mut EventMetadata<Self>) -> R {    f(&mut *NOEVENT_METADATA.write().unwrap())  }}fn test(e: &mut NoEvent) {  println!({}, e.i);  e.i += 1;}fn test2(e: &mut NoEvent) {  println!({}, e.i);}fn main() {  let test_id = EVENT_BUS.register(test, 0);  let mut event = NoEvent { i: 3 };  EVENT_BUS.post(&mut event);  EVENT_BUS.register(test2, 1);  EVENT_BUS.post(&mut event);  EVENT_BUS.unregister(test_id);  EVENT_BUS.post(&mut event);}
Simple type-safe and thread-safe Rust event system
thread safety;event handling;generics;rust;type safety