From 370276fb56fe2a03f1b863eca8e73a2b19d277fb Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 18 Nov 2020 23:47:18 +0000 Subject: [PATCH] hook events --- src/ext.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++ src/server/data.rs | 3 +++ src/server/event.rs | 33 +++++++++++++++++++++++++---- src/server/user.rs | 11 ++-------- 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/ext.rs b/src/ext.rs index 08ceb0a..1e23ae0 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -126,3 +126,54 @@ where S: IntoIterator, } } +/// The ID type used for backing ID types; +pub type GenericID = uuid::Uuid; + + +/// Create a type that contains a (globally) unique ID. +#[macro_export] macro_rules! id_type { + ($name:ident $(: $doc:literal)?) => ($crate::id_type!{pub(self) $name $(: $doc)?}); + ($vis:vis $name:ident $(: $doc:literal)?) => { + $(#[doc=$doc])? + #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] + $vis struct $name($crate::ext::GenericID); + + impl $name + { + /// Create a new unique ID. + #[inline(always)] fn id_new() -> Self + { + Self($crate::ext::GenericID::new_v4()) + } + + /// The generic ID type backing this one + #[inline(always)] fn id_generic(&self) -> &$crate::ext::GenericID + { + &self.0 + } + + /// Consume into the generic ID + #[inline(always)] fn id_into_generic(self) -> $crate::ext::GenericID + { + self.0 + } + + /// Create from a generic ID + #[inline(always)] fn id_from_generic(gen: $crate::ext::GenericID) -> Self + { + Self(gen) + } + } + + impl ::std::fmt::Display for $name + { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result + { + use ::std::fmt::Write; + f.write_str(concat!(stringify!($name),"<"))?; + self.0.fmt(f)?; + f.write_str(">") + } + } + } +} diff --git a/src/server/data.rs b/src/server/data.rs index 378af17..a37caaf 100644 --- a/src/server/data.rs +++ b/src/server/data.rs @@ -112,6 +112,9 @@ pub struct Info tags: Tags, + /// Events to be emitted to `State` when this element does something. + /// + /// Can be used for monitoring or logging and such. hooks: event::Hooks, owner: Option>, //starts as the user that created (i.e. same as `created_by`), or `None` if ownership is disabled diff --git a/src/server/event.rs b/src/server/event.rs index b8cfec0..13b8fbe 100644 --- a/src/server/event.rs +++ b/src/server/event.rs @@ -50,7 +50,7 @@ bitflags! { /// Emmit delete events. const DELETE = 1<<2; - /// Propagate events from children of `Map` datas + /// Propagate events from children of `Map` or `List` datas const CHILD = 1<<3; /// Poke events are opaque events that are fired manually. @@ -68,28 +68,45 @@ impl Default for HookMask } } +id_type!(pub HookID: "The ID of a hook, passed with the event when the hook is fired"); /// Fire events when something happens to this value. #[derive(Debug, Serialize, Deserialize)] pub struct Hooks { filter: HookMask, + id: HookID, +} + +impl Default for Hooks +{ + #[inline] + fn default() -> Self + { + Self { + id: HookID::id_new(), // generate an id now, in case hooks are added later + filter: Default::default(), //default is to emit nothing ever + } + } } /// An event emitted from a matched `Hook`. #[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] -pub enum HookEvent +pub enum HookEventKind { - /// An opaque event type + /// An opaque event type that can only be fired manually. Poke, Read, Write, Delete, + /// An event propagated from a child of this element. + /// + /// This only can happen with `Map` or `List` data kinds. Child(Box), } -impl Default for HookEvent +impl Default for HookEventKind { #[inline] fn default() -> Self @@ -98,3 +115,11 @@ impl Default for HookEvent } } +/// An event emitted from a element value's `Hooks` object. +#[derive(Debug, Clone, PartialEq, Eq, Hash, Ord, PartialOrd)] +pub struct HookEvent +{ + kind: HookEventKind, + /// Corresponds to the `id` field of the `Hooks` object this event was emitted from. + id: HookID, +} diff --git a/src/server/user.rs b/src/server/user.rs index 09d8956..58ea4e6 100644 --- a/src/server/user.rs +++ b/src/server/user.rs @@ -4,16 +4,9 @@ use std::collections::HashMap; use std::borrow::Cow; use bitflags::bitflags; -/// The ID type used for backing user/group IDs -type GenericID = uuid::Uuid; -/// A user group ID -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] -pub struct GroupID(GenericID); - -/// A unique user ID -#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)] -pub struct UserID(GenericID); +id_type!(pub UserID: "A unique user ID"); +id_type!(pub GroupID: "A user group ID"); #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct User