use std::collections::BTreeSet;
use crate::record::Purpose;
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct EmergencyPurposes {
purposes: BTreeSet<Purpose>,
}
impl EmergencyPurposes {
pub fn declare(purposes: &[Purpose]) -> Result<Self, EmergencyError> {
for (index, purpose) in purposes.iter().enumerate() {
if purpose.code.trim().is_empty() {
return Err(EmergencyError::EmptyCode { index });
}
if purpose
.system
.as_deref()
.is_some_and(|system| system.trim().is_empty())
{
return Err(EmergencyError::EmptySystem { index });
}
}
Ok(Self {
purposes: purposes.iter().cloned().collect(),
})
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.purposes.is_empty()
}
pub fn purposes(&self) -> impl Iterator<Item = &Purpose> {
self.purposes.iter()
}
#[must_use]
pub fn mark(&self, declared: &[Purpose]) -> Option<Emergency> {
let marking: BTreeSet<&Purpose> = declared
.iter()
.filter(|purpose| self.purposes.contains(*purpose))
.collect();
(!marking.is_empty()).then(|| Emergency {
purposes: marking.into_iter().cloned().collect(),
consent_set_aside: BTreeSet::new(),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Emergency {
purposes: Vec<Purpose>,
consent_set_aside: BTreeSet<String>,
}
impl Emergency {
#[must_use]
pub fn purposes(&self) -> &[Purpose] {
&self.purposes
}
#[must_use]
pub fn with_consent_set_aside(mut self, members: impl IntoIterator<Item = String>) -> Self {
self.consent_set_aside.extend(members);
self
}
#[must_use]
pub fn consent_set_aside(&self) -> &BTreeSet<String> {
&self.consent_set_aside
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[non_exhaustive]
pub enum EmergencyError {
#[error("emergency purpose {index} has an empty code")]
EmptyCode {
index: usize,
},
#[error("emergency purpose {index} names an empty system")]
EmptySystem {
index: usize,
},
}