Make it impossible to pass invalid `SessionObserver` ids.

- Add an associated type to the `SessionNotifier` trait for the returned Id's instead of using usize.
- Create a new Id type for the `DirectSessionNotifier`'s implementation, wrapping the previously used usize.
- Derive necessary traits of the new wrapper, make internal value inaccessible and Id's not publically constructable.
This commit is contained in:
Drakulix 2017-12-02 14:24:39 +01:00
parent 612436e42d
commit 33286df0d6
2 changed files with 14 additions and 6 deletions

View File

@ -322,13 +322,18 @@ impl Drop for DirectSession {
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct Id(usize);
impl SessionNotifier for DirectSessionNotifier {
fn register<S: SessionObserver + 'static>(&mut self, signal: S) -> usize {
type Id = Id;
fn register<S: SessionObserver + 'static>(&mut self, signal: S) -> Id {
self.signals.push(Some(Box::new(signal)));
self.signals.len() - 1
Id(self.signals.len() - 1)
}
fn unregister(&mut self, signal: usize) {
self.signals[signal] = None;
fn unregister(&mut self, signal: Id) {
self.signals[signal.0] = None;
}
fn is_active(&self) -> bool {

View File

@ -47,12 +47,15 @@ pub trait Session {
/// gets paused or becomes active again. Any object implementing the `SessionObserver` trait
/// may be registered.
pub trait SessionNotifier {
/// Id type of registered observers
type Id: PartialEq + Eq;
/// Registers a given `SessionObserver`.
///
/// Returns an id of the inserted observer, can be used to remove it again.
fn register<S: SessionObserver + 'static>(&mut self, signal: S) -> usize;
fn register<S: SessionObserver + 'static>(&mut self, signal: S) -> Self::Id;
/// Removes an observer by its given id from `SessionNotifier::register`.
fn unregister(&mut self, signal: usize);
fn unregister(&mut self, signal: Self::Id);
/// Check if this session is currently active
fn is_active(&self) -> bool;