use incular_config::ContentSensitivity;
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum ContentSensitivityCapability {
Supported,
#[default]
Unsupported,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ContentSensitivityNoOpReason {
Unsupported,
Unchanged,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ContentSensitivityOutcome {
Applied { sensitivity: ContentSensitivity },
NoOp {
requested: ContentSensitivity,
reason: ContentSensitivityNoOpReason,
},
}
impl ContentSensitivityOutcome {
#[must_use]
pub const fn requested(self) -> ContentSensitivity {
match self {
Self::Applied { sensitivity } => sensitivity,
Self::NoOp { requested, .. } => requested,
}
}
#[must_use]
pub const fn is_noop(self) -> bool {
matches!(self, Self::NoOp { .. })
}
}
pub trait ContentSensitivityBackend {
fn capability(&self) -> ContentSensitivityCapability;
fn apply(&mut self, sensitivity: ContentSensitivity) -> ContentSensitivityOutcome;
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct NoopContentSensitivityBackend;
impl ContentSensitivityBackend for NoopContentSensitivityBackend {
fn capability(&self) -> ContentSensitivityCapability {
ContentSensitivityCapability::Unsupported
}
fn apply(&mut self, sensitivity: ContentSensitivity) -> ContentSensitivityOutcome {
ContentSensitivityOutcome::NoOp {
requested: sensitivity,
reason: ContentSensitivityNoOpReason::Unsupported,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct MemoryContentSensitivityBackend {
capability: ContentSensitivityCapability,
current: ContentSensitivity,
outcomes: Vec<ContentSensitivityOutcome>,
}
impl MemoryContentSensitivityBackend {
#[must_use]
pub fn new(capability: ContentSensitivityCapability) -> Self {
Self {
capability,
current: ContentSensitivity::NotSensitive,
outcomes: Vec::new(),
}
}
#[must_use]
pub fn supported() -> Self {
Self::new(ContentSensitivityCapability::Supported)
}
#[must_use]
pub fn unsupported() -> Self {
Self::new(ContentSensitivityCapability::Unsupported)
}
#[must_use]
pub const fn current(&self) -> ContentSensitivity {
self.current
}
#[must_use]
pub fn outcomes(&self) -> &[ContentSensitivityOutcome] {
&self.outcomes
}
pub fn clear_outcomes(&mut self) {
self.outcomes.clear();
}
}
impl Default for MemoryContentSensitivityBackend {
fn default() -> Self {
Self::supported()
}
}
impl ContentSensitivityBackend for MemoryContentSensitivityBackend {
fn capability(&self) -> ContentSensitivityCapability {
self.capability
}
fn apply(&mut self, sensitivity: ContentSensitivity) -> ContentSensitivityOutcome {
let outcome = match self.capability {
ContentSensitivityCapability::Unsupported => ContentSensitivityOutcome::NoOp {
requested: sensitivity,
reason: ContentSensitivityNoOpReason::Unsupported,
},
ContentSensitivityCapability::Supported if self.current == sensitivity => {
ContentSensitivityOutcome::NoOp {
requested: sensitivity,
reason: ContentSensitivityNoOpReason::Unchanged,
}
}
ContentSensitivityCapability::Supported => {
self.current = sensitivity;
ContentSensitivityOutcome::Applied { sensitivity }
}
};
self.outcomes.push(outcome);
outcome
}
}