use crate::battle::{Battle, BattleRules, BattleState, Version};
use crate::error::{WeaselError, WeaselResult};
use crate::player::PlayerId;
use crate::team::TeamId;
use crate::user::UserEventId;
use log::error;
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::fmt::{Debug, Formatter, Result};
use std::marker::PhantomData;
use std::ops::{Deref, Range};
pub type EventId = u32;
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum EventKind {
DummyEvent,
CreateTeam,
CreateCreature,
CreateObject,
MoveEntity,
StartTurn,
EndTurn,
EndRound,
EnvironmentTurn,
ActivateAbility,
InvokePower,
ApplyImpact,
AlterStatistics,
AlterStatuses,
AlterAbilities,
AlterPowers,
RegenerateStatistics,
RegenerateAbilities,
RegeneratePowers,
InflictStatus,
ClearStatus,
ConvertCreature,
SetRelations,
ConcludeObjectives,
RemoveCreature,
RemoveObject,
RemoveTeam,
AlterSpace,
ResetEntropy,
ResetObjectives,
ResetRounds,
ResetSpace,
EndBattle,
UserEvent(UserEventId),
}
pub enum EventRights<'a, R: BattleRules> {
None,
Server,
Team(&'a TeamId<R>),
Teams(Vec<&'a TeamId<R>>),
}
impl<'a, R: BattleRules> Debug for EventRights<'a, R> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
use EventRights::*;
match self {
None => write!(f, "EventRights::None"),
Server => write!(f, "EventRights::Server"),
Team(id) => write!(f, "EventRights::Team {{ {:?} }}", id),
Teams(ids) => write!(f, "EventRights::Teams {{ {:?} }}", ids),
}
}
}
impl<'a, 'b, R: BattleRules> PartialEq<EventRights<'b, R>> for EventRights<'a, R> {
fn eq(&self, other: &EventRights<'b, R>) -> bool {
use EventRights::*;
match (self, other) {
(None, None) => true,
(Server, Server) => true,
(Team(a), Team(b)) => a == b,
(Teams(a), Teams(b)) => a == b,
_ => false,
}
}
}
impl<'a, R: BattleRules> Eq for EventRights<'a, R> {}
pub trait Event<R: BattleRules>: Debug {
fn verify(&self, battle: &Battle<R>) -> WeaselResult<(), R>;
fn apply(&self, battle: &mut Battle<R>, queue: &mut Option<EventQueue<R>>);
fn kind(&self) -> EventKind;
fn box_clone(&self) -> Box<dyn Event<R> + Send>;
fn as_any(&self) -> &dyn Any;
fn rights<'a>(&'a self, _battle: &'a Battle<R>) -> EventRights<'a, R> {
EventRights::Server
}
}
impl<R: BattleRules> Clone for Box<dyn Event<R> + Send> {
fn clone(&self) -> Box<dyn Event<R> + Send> {
self.box_clone()
}
}
impl<R: BattleRules> PartialEq<Box<dyn Event<R> + Send>> for Box<dyn Event<R> + Send> {
fn eq(&self, other: &Box<dyn Event<R> + Send>) -> bool {
self.kind() == other.kind()
}
}
pub struct EventWrapper<R: BattleRules> {
id: EventId,
origin: Option<EventId>,
pub(crate) event: Box<dyn Event<R> + Send>,
}
impl<R: BattleRules> Clone for EventWrapper<R> {
fn clone(&self) -> Self {
Self::new(self.id, self.origin, self.event.clone())
}
}
impl<R: BattleRules> EventWrapper<R> {
pub(crate) fn new(
id: EventId,
origin: Option<EventId>,
event: Box<dyn Event<R> + Send>,
) -> Self {
Self { id, origin, event }
}
pub fn id(&self) -> EventId {
self.id
}
pub fn origin(&self) -> Option<EventId> {
self.origin
}
#[allow(clippy::borrowed_box)]
pub fn event(&self) -> &Box<dyn Event<R> + Send> {
&self.event
}
pub fn version(self, version: Version<R>) -> VersionedEventWrapper<R> {
VersionedEventWrapper::new(self, version)
}
}
impl<R: BattleRules> Deref for EventWrapper<R> {
type Target = Box<dyn Event<R> + Send>;
fn deref(&self) -> &Self::Target {
&self.event
}
}
pub struct VersionedEventWrapper<R: BattleRules> {
pub(crate) wrapper: EventWrapper<R>,
pub(crate) version: Version<R>,
}
impl<R: BattleRules> Clone for VersionedEventWrapper<R> {
fn clone(&self) -> Self {
Self::new(self.wrapper.clone(), self.version.clone())
}
}
impl<R: BattleRules> VersionedEventWrapper<R> {
pub(crate) fn new(wrapper: EventWrapper<R>, version: Version<R>) -> Self {
Self { wrapper, version }
}
pub fn wrapper(&self) -> &EventWrapper<R> {
&self.wrapper
}
pub fn version(&self) -> &Version<R> {
&self.version
}
}
impl<R: BattleRules> Deref for VersionedEventWrapper<R> {
type Target = EventWrapper<R>;
fn deref(&self) -> &Self::Target {
&self.wrapper
}
}
pub type Condition<R> = std::rc::Rc<dyn Fn(&BattleState<R>) -> bool>;
pub struct EventPrototype<R: BattleRules> {
origin: Option<EventId>,
event: Box<dyn Event<R> + Send>,
condition: Option<Condition<R>>,
}
impl<R: BattleRules> EventPrototype<R> {
pub(crate) fn new(event: Box<dyn Event<R> + Send>) -> Self {
Self {
origin: None,
event,
condition: None,
}
}
pub(crate) fn promote(self, id: EventId) -> EventWrapper<R> {
EventWrapper::new(id, self.origin, self.event)
}
pub fn origin(&self) -> Option<EventId> {
self.origin
}
pub fn set_origin(&mut self, origin: Option<EventId>) {
self.origin = origin;
}
#[allow(clippy::borrowed_box)]
pub fn event(&self) -> &Box<dyn Event<R> + Send> {
&self.event
}
pub fn condition(&self) -> &Option<Condition<R>> {
&self.condition
}
pub fn set_condition(&mut self, condition: Option<Condition<R>>) {
self.condition = condition;
}
pub fn client_prototype(
self,
version: Version<R>,
player: Option<PlayerId>,
) -> ClientEventPrototype<R> {
ClientEventPrototype::new(self.origin, self.event, version, player)
}
}
impl<R: BattleRules> Deref for EventPrototype<R> {
type Target = Box<dyn Event<R> + Send>;
fn deref(&self) -> &Self::Target {
&self.event
}
}
impl<R: BattleRules> Clone for EventPrototype<R> {
fn clone(&self) -> Self {
Self {
origin: self.origin,
event: self.event.clone(),
condition: self.condition.clone(),
}
}
}
pub struct ClientEventPrototype<R: BattleRules> {
origin: Option<EventId>,
pub(crate) event: Box<dyn Event<R> + Send>,
pub(crate) version: Version<R>,
player: Option<PlayerId>,
}
impl<R: BattleRules> ClientEventPrototype<R> {
pub(crate) fn new(
origin: Option<EventId>,
event: Box<dyn Event<R> + Send>,
version: Version<R>,
player: Option<PlayerId>,
) -> Self {
Self {
origin,
event,
version,
player,
}
}
pub fn version(&self) -> &Version<R> {
&self.version
}
pub fn origin(&self) -> Option<EventId> {
self.origin
}
#[allow(clippy::borrowed_box)]
pub fn event(&self) -> &Box<dyn Event<R> + Send> {
&self.event
}
pub(crate) fn prototype(self) -> EventPrototype<R> {
EventPrototype {
origin: self.origin,
event: self.event,
condition: None,
}
}
pub fn authenticate(&mut self, player: PlayerId) {
self.player = Some(player);
}
pub fn player(&self) -> Option<PlayerId> {
self.player
}
}
impl<R: BattleRules> Deref for ClientEventPrototype<R> {
type Target = Box<dyn Event<R> + Send>;
fn deref(&self) -> &Self::Target {
&self.event
}
}
impl<R: BattleRules> Clone for ClientEventPrototype<R> {
fn clone(&self) -> Self {
Self {
origin: self.origin,
event: self.event.clone(),
version: self.version.clone(),
player: self.player,
}
}
}
pub trait DefaultOutput<R: BattleRules> {
type Error: Sized + PartialEq + Debug;
fn ok() -> Self;
fn err(self) -> Option<Self::Error>;
fn result(self) -> WeaselResult<(), R>;
}
pub trait EventProcessor<R: BattleRules> {
type ProcessOutput: DefaultOutput<R>;
fn process(&mut self, event: EventPrototype<R>) -> Self::ProcessOutput;
}
pub trait EventServer<R: BattleRules> {
fn process_client(&mut self, event: ClientEventPrototype<R>) -> WeaselResult<(), R>;
}
pub trait EventReceiver<R: BattleRules> {
fn receive(&mut self, event: VersionedEventWrapper<R>) -> WeaselResult<(), R>;
}
pub trait EventTrigger<'a, R: BattleRules, P: 'a + EventProcessor<R>> {
fn processor(&'a mut self) -> &'a mut P;
fn event(&self) -> Box<dyn Event<R> + Send>;
fn fire(&'a mut self) -> P::ProcessOutput {
let prototype = self.prototype();
self.processor().process(prototype)
}
fn prototype(&self) -> EventPrototype<R> {
EventPrototype::new(self.event())
}
}
pub type EventQueue<R> = Vec<EventPrototype<R>>;
impl<R: BattleRules> EventProcessor<R> for EventQueue<R> {
type ProcessOutput = ();
fn process(&mut self, event: EventPrototype<R>) -> Self::ProcessOutput {
self.push(event);
}
}
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct DummyEvent<R> {
#[cfg_attr(feature = "serialization", serde(skip))]
_phantom: PhantomData<R>,
}
impl<R: BattleRules> DummyEvent<R> {
pub fn trigger<P: EventProcessor<R>>(processor: &mut P) -> DummyEventTrigger<R, P> {
DummyEventTrigger {
processor,
_phantom: PhantomData,
}
}
}
impl<R> Debug for DummyEvent<R> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "DummyEvent {{ }}")
}
}
impl<R> Clone for DummyEvent<R> {
fn clone(&self) -> Self {
Self {
_phantom: PhantomData,
}
}
}
impl<R: BattleRules + 'static> Event<R> for DummyEvent<R> {
fn verify(&self, _: &Battle<R>) -> WeaselResult<(), R> {
Ok(())
}
fn apply(&self, _: &mut Battle<R>, _: &mut Option<EventQueue<R>>) {}
fn kind(&self) -> EventKind {
EventKind::DummyEvent
}
fn box_clone(&self) -> Box<dyn Event<R> + Send> {
Box::new(self.clone())
}
fn as_any(&self) -> &dyn Any {
self
}
fn rights<'a>(&'a self, _battle: &'a Battle<R>) -> EventRights<'a, R> {
EventRights::None
}
}
pub struct DummyEventTrigger<'a, R, P>
where
R: BattleRules,
P: EventProcessor<R>,
{
processor: &'a mut P,
_phantom: PhantomData<R>,
}
impl<'a, R, P> EventTrigger<'a, R, P> for DummyEventTrigger<'a, R, P>
where
R: BattleRules + 'static,
P: EventProcessor<R>,
{
fn processor(&'a mut self) -> &'a mut P {
self.processor
}
fn event(&self) -> Box<dyn Event<R> + Send> {
Box::new(DummyEvent {
_phantom: PhantomData,
})
}
}
impl<R, T> EventProcessor<R> for &mut Option<T>
where
R: BattleRules,
T: EventProcessor<R>,
{
type ProcessOutput = T::ProcessOutput;
fn process(&mut self, event: EventPrototype<R>) -> Self::ProcessOutput {
if let Some(processor) = self {
processor.process(event)
} else {
Self::ProcessOutput::ok()
}
}
}
impl<R, T> EventProcessor<R> for Option<T>
where
R: BattleRules,
T: EventProcessor<R>,
{
type ProcessOutput = T::ProcessOutput;
fn process(&mut self, event: EventPrototype<R>) -> Self::ProcessOutput {
if let Some(processor) = self {
processor.process(event)
} else {
Self::ProcessOutput::ok()
}
}
}
impl<R> EventProcessor<R> for ()
where
R: BattleRules,
{
type ProcessOutput = WeaselResult<(), R>;
fn process(&mut self, _: EventPrototype<R>) -> Self::ProcessOutput {
Err(WeaselError::EmptyEventProcessor)
}
}
impl<R: BattleRules> DefaultOutput<R> for () {
type Error = ();
fn ok() -> Self {}
fn err(self) -> Option<Self::Error> {
None
}
fn result(self) -> WeaselResult<(), R> {
Ok(())
}
}
pub struct Prioritized<'a, R: BattleRules> {
event_queue: &'a mut EventQueue<R>,
}
impl<'a, R: BattleRules> Prioritized<'a, R> {
pub fn new(event_queue: &'a mut EventQueue<R>) -> Self {
Self { event_queue }
}
}
impl<R> EventProcessor<R> for Prioritized<'_, R>
where
R: BattleRules,
{
type ProcessOutput = ();
fn process(&mut self, event: EventPrototype<R>) -> Self::ProcessOutput {
self.event_queue.insert(0, event);
}
}
pub struct LinkedQueue<'a, R: BattleRules> {
event_queue: &'a mut EventQueue<R>,
origin: Option<EventId>,
}
impl<'a, R: BattleRules> LinkedQueue<'a, R> {
pub fn new(event_queue: &'a mut EventQueue<R>, origin: Option<EventId>) -> Self {
Self {
event_queue,
origin,
}
}
}
impl<R> EventProcessor<R> for LinkedQueue<'_, R>
where
R: BattleRules,
{
type ProcessOutput = ();
fn process(&mut self, mut event: EventPrototype<R>) -> Self::ProcessOutput {
if event.origin().is_none() {
event.set_origin(self.origin);
}
self.event_queue.push(event);
}
}
pub struct Conditional<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
{
trigger: T,
condition: Condition<R>,
_phantom: PhantomData<&'a P>,
}
impl<'a, R, T, P> Conditional<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
Condition<R>: Clone,
{
pub fn new(trigger: T, condition: Condition<R>) -> Self {
Self {
trigger,
condition,
_phantom: PhantomData,
}
}
}
impl<'a, R, T, P> EventTrigger<'a, R, P> for Conditional<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
Condition<R>: Clone,
{
fn processor(&'a mut self) -> &'a mut P {
self.trigger.processor()
}
fn event(&self) -> Box<dyn Event<R> + Send> {
self.trigger.event()
}
fn prototype(&self) -> EventPrototype<R> {
let mut prototype = self.trigger.prototype();
prototype.set_condition(Some(self.condition.clone()));
prototype
}
}
pub type EventSinkId = u16;
pub trait EventSink {
fn id(&self) -> EventSinkId;
fn on_disconnect(&mut self) {}
}
pub trait ClientSink<R: BattleRules>: EventSink {
fn send(&mut self, event: &VersionedEventWrapper<R>) -> WeaselResult<(), R>;
}
pub trait ServerSink<R: BattleRules>: EventSink {
fn send(&mut self, event: &ClientEventPrototype<R>) -> WeaselResult<(), R>;
}
pub(crate) struct MultiClientSink<R: BattleRules> {
sinks: Vec<Box<dyn ClientSink<R> + Send>>,
}
impl<R: BattleRules> MultiClientSink<R> {
pub(crate) fn new() -> Self {
Self { sinks: Vec::new() }
}
fn add(&mut self, sink: Box<dyn ClientSink<R> + Send>) -> WeaselResult<(), R> {
if self.sinks.iter().any(|e| e.id() == sink.id()) {
Err(WeaselError::DuplicatedEventSink(sink.id()))
} else {
self.sinks.push(sink);
Ok(())
}
}
fn send<I>(&mut self, id: EventSinkId, events: I) -> WeaselResult<(), R>
where
I: Iterator<Item = VersionedEventWrapper<R>>,
{
let index = self.sinks.iter().position(|e| e.id() == id);
if let Some(index) = index {
for event in events {
let sink = &mut self.sinks[index];
let result = sink.send(&event);
if result.is_err() {
sink.on_disconnect();
self.sinks.remove(index);
}
result?;
}
Ok(())
} else {
Err(WeaselError::EventSinkNotFound(id))
}
}
fn remove(&mut self, id: EventSinkId) {
let index = self.sinks.iter().position(|e| e.id() == id);
if let Some(index) = index {
self.sinks.remove(index);
}
}
pub(crate) fn send_all(&mut self, event: &VersionedEventWrapper<R>) {
let mut failed_sinks_index = Vec::new();
for (i, sink) in self.sinks.iter_mut().enumerate() {
sink.send(event).unwrap_or_else(|err| {
error!("{:?}", err);
failed_sinks_index.push(i)
});
}
for i in failed_sinks_index {
self.sinks[i].on_disconnect();
self.sinks.remove(i);
}
}
fn sinks(&self) -> impl Iterator<Item = &Box<dyn ClientSink<R> + Send>> {
self.sinks.iter()
}
}
pub struct MultiClientSinkHandle<'a, R>
where
R: BattleRules,
{
sinks: &'a MultiClientSink<R>,
}
impl<'a, R> MultiClientSinkHandle<'a, R>
where
R: BattleRules + 'static,
{
pub(crate) fn new(sinks: &'a MultiClientSink<R>) -> Self {
Self { sinks }
}
pub fn sinks(&self) -> impl Iterator<Item = &Box<dyn ClientSink<R> + Send>> {
self.sinks.sinks()
}
}
pub struct MultiClientSinkHandleMut<'a, R>
where
R: BattleRules + 'static,
{
sinks: &'a mut MultiClientSink<R>,
battle: &'a Battle<R>,
}
impl<'a, R> MultiClientSinkHandleMut<'a, R>
where
R: BattleRules + 'static,
{
pub(crate) fn new(sinks: &'a mut MultiClientSink<R>, battle: &'a Battle<R>) -> Self {
Self { sinks, battle }
}
pub fn add_sink(&mut self, sink: Box<dyn ClientSink<R> + Send>) -> WeaselResult<(), R> {
self.sinks.add(sink)
}
pub fn add_sink_from(
&mut self,
sink: Box<dyn ClientSink<R> + Send>,
event_id: EventId,
) -> WeaselResult<(), R> {
self.add_sink_range(
sink,
Range {
start: event_id,
end: self.battle.history().len(),
},
)
}
pub fn add_sink_range(
&mut self,
sink: Box<dyn ClientSink<R> + Send>,
range: Range<EventId>,
) -> WeaselResult<(), R> {
let range = normalize_range(range, self.battle.history().len())?;
let sink_id = sink.id();
self.sinks.add(sink)?;
self.sinks
.send(sink_id, self.battle.versioned_events(range))
}
pub fn send_range(&mut self, id: EventSinkId, range: Range<EventId>) -> WeaselResult<(), R> {
let range = normalize_range(range, self.battle.history().len())?;
self.sinks.send(id, self.battle.versioned_events(range))
}
pub fn remove_sink(&mut self, id: EventSinkId) {
self.sinks.remove(id);
}
pub fn sinks(&self) -> impl Iterator<Item = &Box<dyn ClientSink<R> + Send>> {
self.sinks.sinks()
}
}
fn normalize_range<R: BattleRules>(
range: Range<EventId>,
history_len: EventId,
) -> WeaselResult<Range<usize>, R> {
if range.start > range.end || range.end > history_len {
return Err(WeaselError::InvalidEventRange(range, history_len));
}
let range: Range<usize> = Range {
start: range.start as usize,
end: range.end as usize,
};
Ok(range)
}
pub struct Originated<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
{
trigger: T,
origin: EventId,
_phantom: PhantomData<&'a P>,
_phantom_: PhantomData<R>,
}
impl<'a, R, T, P> Originated<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
{
pub fn new(trigger: T, origin: EventId) -> Self {
Self {
trigger,
origin,
_phantom: PhantomData,
_phantom_: PhantomData,
}
}
}
impl<'a, R, T, P> EventTrigger<'a, R, P> for Originated<'a, R, T, P>
where
R: BattleRules,
T: EventTrigger<'a, R, P>,
P: 'a + EventProcessor<R>,
{
fn processor(&'a mut self) -> &'a mut P {
self.trigger.processor()
}
fn event(&self) -> Box<dyn Event<R> + Send> {
self.trigger.event()
}
fn prototype(&self) -> EventPrototype<R> {
let mut prototype = self.trigger.prototype();
prototype.set_origin(Some(self.origin));
prototype
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::entropy::ResetEntropy;
use crate::{battle_rules, rules::empty::*};
use std::iter::once;
battle_rules! {}
#[test]
fn event_equality() {
let dummy = DummyEvent::<CustomRules>::trigger(&mut ()).event();
let dummy_copy = dummy.clone();
let reset_entropy = ResetEntropy::<CustomRules>::trigger(&mut ()).event();
assert_eq!(&dummy, &dummy_copy);
assert_ne!(&dummy, &reset_entropy);
}
#[test]
fn multi_client_sink() {
struct Sink {
id: EventSinkId,
ok: bool,
}
impl EventSink for Sink {
fn id(&self) -> EventSinkId {
self.id
}
}
impl ClientSink<CustomRules> for Sink {
fn send(
&mut self,
_: &VersionedEventWrapper<CustomRules>,
) -> WeaselResult<(), CustomRules> {
if self.ok {
Ok(())
} else {
Err(WeaselError::EventSinkError("broken".to_string()))
}
}
}
let mut multi = MultiClientSink::new();
assert_eq!(multi.add(Box::new(Sink { id: 0, ok: true })).err(), None);
assert_eq!(multi.sinks.len(), 1);
assert_eq!(
multi.add(Box::new(Sink { id: 0, ok: true })).err(),
Some(WeaselError::DuplicatedEventSink(0))
);
assert_eq!(multi.sinks.len(), 1);
multi.remove(2);
assert_eq!(multi.sinks.len(), 1);
multi.remove(0);
assert_eq!(multi.sinks.len(), 0);
assert_eq!(multi.add(Box::new(Sink { id: 0, ok: true })).err(), None);
assert_eq!(multi.add(Box::new(Sink { id: 1, ok: false })).err(), None);
assert_eq!(multi.sinks.len(), 2);
let event = DummyEvent::<CustomRules>::trigger(&mut ())
.prototype()
.promote(0)
.version(0);
multi.send_all(&event);
assert_eq!(multi.sinks.len(), 1);
assert_eq!(multi.send(0, once(event.clone())).err(), None);
assert_eq!(
multi.send(2, once(event.clone())).err(),
Some(WeaselError::EventSinkNotFound(2))
);
assert_eq!(multi.add(Box::new(Sink { id: 1, ok: false })).err(), None);
assert_eq!(multi.sinks.len(), 2);
assert_eq!(
multi.send(1, once(event)).err(),
Some(WeaselError::EventSinkError("broken".to_string()))
);
assert_eq!(multi.sinks.len(), 1);
}
#[test]
#[allow(clippy::let_unit_value)]
fn decorators_stack() {
let mut processor = ();
let event = Conditional::new(
DummyEvent::trigger(&mut processor),
std::rc::Rc::new(|_: &BattleState<CustomRules>| true),
);
let event = Originated::new(event, 0);
let prototype = event.prototype();
assert!(prototype.condition.is_some());
assert!(prototype.origin.is_some());
}
#[test]
fn linked_queue_respects_origin() {
let mut queue = EventQueue::<CustomRules>::new();
let origin = 42;
let mut linked_queue = LinkedQueue::new(&mut queue, Some(origin + 1));
Originated::new(DummyEvent::trigger(&mut linked_queue), origin).fire();
assert_eq!(queue[0].origin(), Some(origin));
}
#[test]
fn basic_event_rights_equality() {
type R = CustomRules;
use EventRights::*;
assert_eq!(EventRights::<R>::None, None);
assert_ne!(EventRights::<R>::None, Team(&1));
assert_ne!(EventRights::<R>::None, Teams(vec![&1]));
assert_eq!(EventRights::<R>::Server, Server);
assert_ne!(EventRights::<R>::Server, Team(&1));
assert_ne!(EventRights::<R>::Server, Teams(vec![&1]));
assert_eq!(EventRights::<R>::Team(&1), Team(&1));
assert_ne!(EventRights::<R>::Team(&1), Team(&2));
assert_eq!(EventRights::<R>::Teams(vec![&1, &2]), Teams(vec![&1, &2]));
assert_ne!(EventRights::<R>::Teams(vec![&1, &2]), Teams(vec![&1, &3]));
assert_ne!(EventRights::<R>::Team(&1), Teams(vec![&1]));
}
}