use super::PluginWorkspaceIoBudgetField;
use crate::plugin::PluginIdentity;
use std::{
fmt::{Debug, Display, Formatter},
num::NonZeroUsize,
};
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum PluginWorkspaceIoIdentityMismatchSource {
AccessProof,
RequestLedger,
}
impl PluginWorkspaceIoIdentityMismatchSource {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::AccessProof => "access-proof",
Self::RequestLedger => "request-ledger",
}
}
}
impl Display for PluginWorkspaceIoIdentityMismatchSource {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
impl Debug for PluginWorkspaceIoIdentityMismatchSource {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub enum PluginWorkspaceIoCommitErrorKind {
ZeroLimit,
PayloadTooLarge,
TooManyRequests,
IdentityMismatch,
}
impl PluginWorkspaceIoCommitErrorKind {
#[must_use]
pub const fn as_str(self) -> &'static str {
match self {
Self::ZeroLimit => "zero-limit",
Self::PayloadTooLarge => "payload-too-large",
Self::TooManyRequests => "too-many-requests",
Self::IdentityMismatch => "identity-mismatch",
}
}
}
impl Display for PluginWorkspaceIoCommitErrorKind {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
impl Debug for PluginWorkspaceIoCommitErrorKind {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum PluginWorkspaceIoCommitError {
ZeroLimit {
field: PluginWorkspaceIoBudgetField,
},
PayloadTooLarge {
size: u64,
max_size: u64,
},
TooManyRequests {
identity: PluginIdentity,
limit: NonZeroUsize,
},
IdentityMismatch {
mismatch_source: PluginWorkspaceIoIdentityMismatchSource,
batch_identity: PluginIdentity,
provided_identity: PluginIdentity,
},
}
impl PluginWorkspaceIoCommitError {
#[must_use]
pub const fn kind(&self) -> PluginWorkspaceIoCommitErrorKind {
match self {
Self::ZeroLimit { .. } => PluginWorkspaceIoCommitErrorKind::ZeroLimit,
Self::PayloadTooLarge { .. } => PluginWorkspaceIoCommitErrorKind::PayloadTooLarge,
Self::TooManyRequests { .. } => PluginWorkspaceIoCommitErrorKind::TooManyRequests,
Self::IdentityMismatch { .. } => PluginWorkspaceIoCommitErrorKind::IdentityMismatch,
}
}
}
impl Display for PluginWorkspaceIoCommitError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::ZeroLimit { field } => {
write!(
formatter,
"plugin workspace I/O budget {field} must be non-zero"
)
}
Self::PayloadTooLarge { size, max_size } => write!(
formatter,
"plugin workspace payload is {size} bytes, exceeding the {max_size} byte limit"
),
Self::TooManyRequests { identity, limit } => {
let identity = identity.as_str();
let limit = limit.get();
write!(
formatter,
"plugin {identity:?} exceeded workspace I/O request limit of {limit}"
)
}
Self::IdentityMismatch {
mismatch_source,
batch_identity,
provided_identity,
} => {
let batch_identity = batch_identity.as_str();
let provided_identity = provided_identity.as_str();
match mismatch_source {
PluginWorkspaceIoIdentityMismatchSource::AccessProof => write!(
formatter,
"plugin workspace I/O access proof for {provided_identity:?} cannot be queued by {batch_identity:?}"
),
PluginWorkspaceIoIdentityMismatchSource::RequestLedger => write!(
formatter,
"plugin workspace I/O request ledger for {provided_identity:?} cannot be paired with task batch {batch_identity:?}"
),
}
}
}
}
}