use super::display::EditShape;
use crate::{
buffer::BufferEditShape,
ecs::events::edit::{
PluginBufferEditProposalReceipt, PluginBufferEditProposalReceiptOutcome,
PluginBufferEditProposalReceiptOwner, PluginBufferEditProposalReceiptRejectionReason,
PluginBufferProposalCapability,
},
text_stream::TextRevision,
};
use std::fmt::{Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct PluginRuntimeTraceProposalReceipt {
proposal: u64,
capability: PluginBufferProposalCapability,
target: PluginRuntimeTraceTarget,
base_revision: TextRevision,
proposed: BufferEditShape,
outcome: PluginRuntimeTraceProposalOutcome,
}
impl PluginRuntimeTraceProposalReceipt {
#[must_use]
pub const fn proposal(&self) -> u64 {
self.proposal
}
#[must_use]
pub const fn capability(&self) -> PluginBufferProposalCapability {
self.capability
}
#[must_use]
pub const fn target(&self) -> PluginRuntimeTraceTarget {
self.target
}
#[must_use]
pub const fn base_revision(&self) -> TextRevision {
self.base_revision
}
#[must_use]
pub const fn proposed(&self) -> &BufferEditShape {
&self.proposed
}
#[must_use]
pub const fn outcome(&self) -> &PluginRuntimeTraceProposalOutcome {
&self.outcome
}
}
impl From<&PluginBufferEditProposalReceipt> for PluginRuntimeTraceProposalReceipt {
fn from(receipt: &PluginBufferEditProposalReceipt) -> Self {
Self {
proposal: receipt.proposal().get(),
capability: receipt.capability(),
target: PluginRuntimeTraceTarget::Buffer,
base_revision: receipt.base_revision(),
proposed: receipt.proposed().clone(),
outcome: PluginRuntimeTraceProposalOutcome::from(receipt.outcome()),
}
}
}
impl Display for PluginRuntimeTraceProposalReceipt {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
write!(
formatter,
"proposal={} capability={} target={} base_revision={} proposed={} outcome={}",
self.proposal,
self.capability.as_str(),
self.target,
self.base_revision,
EditShape(&self.proposed),
self.outcome
)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PluginRuntimeTraceTarget {
Buffer,
}
impl PluginRuntimeTraceTarget {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::Buffer => "buffer",
}
}
}
impl Display for PluginRuntimeTraceTarget {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PluginRuntimeTraceProposalOutcome {
Applied {
previous_revision: TextRevision,
current_revision: TextRevision,
},
Rejected {
owner: PluginRuntimeTraceProposalOwner,
reason: PluginRuntimeTraceProposalRejection,
},
}
impl From<&PluginBufferEditProposalReceiptOutcome> for PluginRuntimeTraceProposalOutcome {
fn from(outcome: &PluginBufferEditProposalReceiptOutcome) -> Self {
match outcome {
PluginBufferEditProposalReceiptOutcome::Applied {
previous_revision,
current_revision,
} => Self::Applied {
previous_revision: previous_revision.revision,
current_revision: current_revision.revision,
},
PluginBufferEditProposalReceiptOutcome::Rejected { owner, reason } => Self::Rejected {
owner: PluginRuntimeTraceProposalOwner::from(*owner),
reason: PluginRuntimeTraceProposalRejection::from(reason),
},
}
}
}
impl Display for PluginRuntimeTraceProposalOutcome {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::Applied {
previous_revision,
current_revision,
} => write!(
formatter,
"applied previous_revision={previous_revision} current_revision={current_revision}"
),
Self::Rejected { owner, reason } => {
write!(formatter, "rejected owner={owner} reason={reason}")
}
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PluginRuntimeTraceProposalOwner {
ProposalLane,
BufferOwner,
}
impl PluginRuntimeTraceProposalOwner {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::ProposalLane => "proposal-lane",
Self::BufferOwner => "buffer-owner",
}
}
}
impl From<PluginBufferEditProposalReceiptOwner> for PluginRuntimeTraceProposalOwner {
fn from(owner: PluginBufferEditProposalReceiptOwner) -> Self {
match owner {
PluginBufferEditProposalReceiptOwner::ProposalLane => Self::ProposalLane,
PluginBufferEditProposalReceiptOwner::BufferOwner => Self::BufferOwner,
}
}
}
impl Display for PluginRuntimeTraceProposalOwner {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PluginRuntimeTraceProposalRejection {
RejectedBeforeOwner,
MissingTarget,
InvalidEdit,
StaleRevision {
expected: TextRevision,
actual: TextRevision,
},
}
impl PluginRuntimeTraceProposalRejection {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::RejectedBeforeOwner => "rejected-before-owner",
Self::MissingTarget => "missing-target",
Self::InvalidEdit => "invalid-edit",
Self::StaleRevision { .. } => "stale-revision",
}
}
}
impl From<&PluginBufferEditProposalReceiptRejectionReason> for PluginRuntimeTraceProposalRejection {
fn from(reason: &PluginBufferEditProposalReceiptRejectionReason) -> Self {
match reason {
PluginBufferEditProposalReceiptRejectionReason::RejectedBeforeOwner => {
Self::RejectedBeforeOwner
}
PluginBufferEditProposalReceiptRejectionReason::MissingTarget => Self::MissingTarget,
PluginBufferEditProposalReceiptRejectionReason::InvalidEdit { .. } => Self::InvalidEdit,
PluginBufferEditProposalReceiptRejectionReason::StaleRevision { expected, actual } => {
Self::StaleRevision {
expected: *expected,
actual: *actual,
}
}
}
}
}
impl Display for PluginRuntimeTraceProposalRejection {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::StaleRevision { expected, actual } => {
write!(
formatter,
"stale-revision expected={expected} actual={actual}"
)
}
_ => formatter.write_str(self.as_str()),
}
}
}