blob: 40c6d3bc61639993222949eea7b01c88a16ab4f5 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::model::{
events::{error::EventsError, event::EventMode},
walk_state::WalkStateUnit,
};
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct EventModeSet {
supports_sync: bool,
}
impl EventModeSet {
pub fn new(mode: cm_rust::EventMode) -> Self {
Self { supports_sync: mode == cm_rust::EventMode::Sync }
}
pub fn debug() -> Self {
Self { supports_sync: true }
}
pub fn supports_mode(&self, mode: &EventMode) -> bool {
match mode {
EventMode::Sync => self.supports_sync,
EventMode::Async => true,
}
}
}
impl WalkStateUnit for EventModeSet {
type Error = EventsError;
/// Ensures the next walk state of filters is a superset of the current state.
///
/// Consider A->B where A (next_state) is offering an event to B (self) and B is using it itself
/// or offering it again.
///
/// For all properties of B, those properties are in A and they are subsets of the property in
/// B.
fn validate_next(&self, next_state: &EventModeSet) -> Result<(), Self::Error> {
match (self.supports_sync, next_state.supports_sync) {
(_, true) => Ok(()),
(false, false) => Ok(()),
(true, false) => {
Err(EventsError::CannotPropagateEventMode { event_mode: EventMode::Sync })
}
}
}
fn finalize_error() -> Self::Error {
EventsError::MissingModes
}
}
#[cfg(test)]
mod tests {
use {super::*, crate::model::events::event::EventMode, matches::assert_matches};
#[test]
fn test_walk_state() {
let async_filter = EventModeSet::new(cm_rust::EventMode::Async);
let sync_filter = EventModeSet::new(cm_rust::EventMode::Sync);
assert_matches!(async_filter.validate_next(&async_filter), Ok(()));
assert_matches!(
sync_filter.validate_next(&async_filter),
Err(EventsError::CannotPropagateEventMode { event_mode: EventMode::Sync })
);
assert_matches!(async_filter.validate_next(&sync_filter), Ok(()));
assert_matches!(async_filter.validate_next(&async_filter), Ok(()));
}
#[test]
fn contains() {
let async_filter = EventModeSet::new(cm_rust::EventMode::Async);
let sync_filter = EventModeSet::new(cm_rust::EventMode::Sync);
assert!(async_filter.supports_mode(&EventMode::Async));
assert!(sync_filter.supports_mode(&EventMode::Sync));
assert!(!async_filter.supports_mode(&EventMode::Sync));
assert!(sync_filter.supports_mode(&EventMode::Sync));
}
}