use crate::model::attempt_journal::OperationBindingRecord;
use thiserror::Error;
pub const MAX_CONTROLLERS: usize = 10;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ControllerSet {
principals: Vec<String>,
}
impl ControllerSet {
pub fn new(principals: Vec<String>) -> Result<Self, ControlObservationError> {
let principals = super::principal::canonical_set(
principals,
MAX_CONTROLLERS,
|| ControlObservationError::TooManyControllers,
|| ControlObservationError::InvalidPrincipal,
|| ControlObservationError::DuplicateController,
)?;
Ok(Self { principals })
}
#[must_use]
pub fn principals(&self) -> &[String] {
&self.principals
}
#[must_use]
pub fn contains_caller(&self, binding: &OperationBindingRecord) -> bool {
self.principals
.binary_search_by(|principal| principal.as_str().cmp(binding.caller()))
.is_ok()
}
}
#[derive(Debug, Eq, Error, PartialEq)]
pub enum ControlObservationError {
#[error("invalid control observation principal")]
InvalidPrincipal,
#[error("controller set exceeds {MAX_CONTROLLERS}")]
TooManyControllers,
#[error("duplicate controller principal")]
DuplicateController,
}
#[cfg(test)]
mod tests;