use crate::output_payload::{OutputPayload, StoredOutput};
use crate::{MaterializedOutput, OutputKey, Revision, ScopeId, TransactionId};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ClearReason {
ScopeClosed,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RebaselineReason {
Requested,
}
#[derive(Clone, Debug, PartialEq)]
pub enum OutputFrameKind {
Baseline(OutputPayload),
Delta(OutputPayload),
Clear(ClearReason),
Rebaseline(OutputPayload, RebaselineReason),
}
impl OutputFrameKind {
pub fn baseline<T>(value: T) -> Self
where
T: Clone + PartialEq + Send + Sync + 'static,
{
Self::Baseline(OutputPayload::new(value))
}
pub fn delta<T>(value: T) -> Self
where
T: Clone + PartialEq + Send + Sync + 'static,
{
Self::Delta(OutputPayload::new(value))
}
pub fn rebaseline<T>(value: T, reason: RebaselineReason) -> Self
where
T: Clone + PartialEq + Send + Sync + 'static,
{
Self::Rebaseline(OutputPayload::new(value), reason)
}
pub(crate) fn baseline_from_stored(value: Box<dyn StoredOutput>) -> Self {
Self::Baseline(OutputPayload::from_stored(value))
}
pub(crate) fn delta_from_stored(value: Box<dyn StoredOutput>) -> Self {
Self::Delta(OutputPayload::from_stored(value))
}
pub(crate) fn rebaseline_from_stored(
value: Box<dyn StoredOutput>,
reason: RebaselineReason,
) -> Self {
Self::Rebaseline(OutputPayload::from_stored(value), reason)
}
pub fn payload<T>(&self) -> Option<&T>
where
T: Clone + PartialEq + Send + Sync + 'static,
{
match self {
Self::Baseline(payload) | Self::Delta(payload) | Self::Rebaseline(payload, _) => {
payload.get::<T>()
}
Self::Clear(_) => None,
}
}
pub fn clear_reason(&self) -> Option<ClearReason> {
match self {
Self::Clear(reason) => Some(*reason),
_ => None,
}
}
pub fn rebaseline_reason(&self) -> Option<RebaselineReason> {
match self {
Self::Rebaseline(_, reason) => Some(*reason),
_ => None,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct OutputFrame {
pub output_key: OutputKey,
pub scope: ScopeId,
pub transaction_id: TransactionId,
pub revision: Revision,
pub kind: OutputFrameKind,
}
impl OutputFrame {
pub fn payload_for<T>(&self, output: &MaterializedOutput<T>) -> Option<&T>
where
T: Clone + PartialEq + Send + Sync + 'static,
{
(self.output_key == output.key())
.then(|| self.kind.payload::<T>())
.flatten()
}
}