use super::super::{
PluginHandleError, PluginHandleShape, PluginWorkspaceObserveTaskReserveError,
effect::PluginEffectCommitError, workspace_io::PluginWorkspaceIoCommitError,
};
use super::resource::{PluginHostResourceKind, PluginResourceHandleRejectionReason};
use crate::plugin::{
GuestDecodeError, PluginAuthorizationError, PluginIdentity, PluginOperationalImportRejection,
};
use std::fmt::{Debug, Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum PluginBufferObservationError {
MissingSnapshot {
handle: PluginHandleShape,
},
TextTooLarge {
handle: PluginHandleShape,
byte_len: u64,
max: u64,
},
}
impl Display for PluginBufferObservationError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::MissingSnapshot { handle } => write!(
formatter,
"plugin buffer observation for {} handle lacks captured text",
handle.kind()
),
Self::TextTooLarge { byte_len, max, .. } => write!(
formatter,
"plugin buffer observation text has {byte_len} bytes, exceeding {max}"
),
}
}
}
#[derive(Clone, Eq, PartialEq, thiserror::Error)]
#[non_exhaustive]
pub enum PluginHostImportError {
HostStateMismatch(#[source] PluginHostStateMismatch),
Authorization(#[source] PluginAuthorizationError),
Handle(#[source] PluginHandleError),
Effect(#[source] PluginEffectCommitError),
WorkspaceIo(#[source] PluginWorkspaceIoCommitError),
WorkspaceObserveTask(#[source] PluginWorkspaceObserveTaskReserveError),
Observation(#[source] PluginBufferObservationError),
Decode(#[source] GuestDecodeError),
ResourceHandle {
kind: PluginHostResourceKind,
reason: PluginResourceHandleRejectionReason,
},
SessionMissing,
SessionAlreadyActive,
MissingObservedRevision {
handle: PluginHandleShape,
},
}
impl PluginHostImportError {
#[must_use]
const fn kind(&self) -> PluginHostImportErrorKind {
match self {
Self::HostStateMismatch(_) => PluginHostImportErrorKind::HostStateMismatch,
Self::Authorization(_) => PluginHostImportErrorKind::Authorization,
Self::Handle(_) => PluginHostImportErrorKind::Handle,
Self::Effect(_) => PluginHostImportErrorKind::Effect,
Self::WorkspaceIo(_) => PluginHostImportErrorKind::WorkspaceIo,
Self::WorkspaceObserveTask(_) => PluginHostImportErrorKind::WorkspaceObserveTask,
Self::Observation(_) => PluginHostImportErrorKind::Observation,
Self::Decode(_) => PluginHostImportErrorKind::Decode,
Self::ResourceHandle { .. } => PluginHostImportErrorKind::ResourceHandle,
Self::SessionMissing => PluginHostImportErrorKind::SessionMissing,
Self::SessionAlreadyActive => PluginHostImportErrorKind::SessionAlreadyActive,
Self::MissingObservedRevision { .. } => {
PluginHostImportErrorKind::MissingObservedRevision
}
}
}
#[must_use]
pub const fn operational_rejection(&self) -> Option<PluginOperationalImportRejection> {
match self {
Self::HostStateMismatch(_) => Some(PluginOperationalImportRejection::HostStateMismatch),
Self::Authorization(_) => None,
Self::Handle(_) => Some(PluginOperationalImportRejection::Handle),
Self::Effect(_) => Some(PluginOperationalImportRejection::EffectQueue),
Self::WorkspaceIo(_) => Some(PluginOperationalImportRejection::WorkspaceIoQueue),
Self::WorkspaceObserveTask(source) => Some(source.operational_rejection()),
Self::Observation(_) => Some(PluginOperationalImportRejection::Observation),
Self::Decode(_) => Some(PluginOperationalImportRejection::Decode),
Self::ResourceHandle { .. } => Some(PluginOperationalImportRejection::ResourceHandle),
Self::SessionMissing => Some(PluginOperationalImportRejection::SessionMissing),
Self::SessionAlreadyActive => {
Some(PluginOperationalImportRejection::SessionAlreadyActive)
}
Self::MissingObservedRevision { .. } => {
Some(PluginOperationalImportRejection::MissingObservedRevision)
}
}
}
}
impl Debug for PluginHostImportError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
let mut debug = formatter.debug_struct("PluginHostImportError");
let _debug = debug.field("kind", &self.kind());
let _debug = debug.field("operational_rejection", &self.operational_rejection());
match self {
Self::HostStateMismatch(source) => {
let _debug = debug.field("source", source);
}
Self::Authorization(source) => {
let _debug = debug.field("source", source);
}
Self::Handle(source) => {
let _debug = debug.field("source", source);
}
Self::Effect(source) => {
let _debug = debug.field("source", source);
}
Self::WorkspaceIo(source) => {
let _debug = debug.field("source", source);
}
Self::WorkspaceObserveTask(source) => {
let _debug = debug.field("source", source);
}
Self::Observation(source) => {
let _debug = debug.field("source", source);
}
Self::Decode(source) => {
let _debug = debug.field("source", source);
}
Self::ResourceHandle { kind, reason } => {
let _debug = debug.field("resource_kind", kind);
let _debug = debug.field("reason", reason);
}
Self::SessionMissing | Self::SessionAlreadyActive => {}
Self::MissingObservedRevision { handle } => {
let _debug = debug.field("handle", handle);
}
}
debug.finish()
}
}
#[derive(Clone, Copy, Eq, PartialEq)]
pub(super) enum PluginHostImportErrorKind {
HostStateMismatch,
Authorization,
Handle,
Effect,
WorkspaceIo,
WorkspaceObserveTask,
Observation,
Decode,
ResourceHandle,
SessionMissing,
SessionAlreadyActive,
MissingObservedRevision,
}
impl PluginHostImportErrorKind {
pub(super) const fn as_str(self) -> &'static str {
match self {
Self::HostStateMismatch => "host-state-mismatch",
Self::Authorization => "authorization",
Self::Handle => "handle",
Self::Effect => "effect",
Self::WorkspaceIo => "workspace-io",
Self::WorkspaceObserveTask => "workspace-observe-task",
Self::Observation => "observation",
Self::Decode => "decode",
Self::ResourceHandle => "resource-handle",
Self::SessionMissing => "session-missing",
Self::SessionAlreadyActive => "session-already-active",
Self::MissingObservedRevision => "missing-observed-revision",
}
}
}
impl Debug for PluginHostImportErrorKind {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
impl Display for PluginHostImportErrorKind {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
formatter.write_str(self.as_str())
}
}
impl Display for PluginHostImportError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
match self {
Self::HostStateMismatch(source) => {
write!(formatter, "plugin import host state denied: {source}")
}
Self::Authorization(source) => write!(formatter, "plugin import denied: {source}"),
Self::Handle(source) => write!(formatter, "plugin import handle denied: {source}"),
Self::Effect(source) => write!(formatter, "plugin import effect denied: {source}"),
Self::WorkspaceIo(source) => {
write!(formatter, "plugin import workspace I/O denied: {source}")
}
Self::WorkspaceObserveTask(source) => {
write!(
formatter,
"plugin import workspace observation task denied: {source}"
)
}
Self::Observation(source) => {
write!(formatter, "plugin import observation denied: {source}")
}
Self::Decode(source) => write!(formatter, "plugin import decode denied: {source}"),
Self::ResourceHandle { kind, reason } => {
write!(formatter, "plugin import resource {kind} denied: {reason}")
}
Self::SessionMissing => {
formatter.write_str("plugin import attempted outside active update")
}
Self::SessionAlreadyActive => {
formatter.write_str("plugin import attempted to start a nested update")
}
Self::MissingObservedRevision { handle } => write!(
formatter,
"plugin buffer edit for {} handle lacks observed revision",
handle.kind()
),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, thiserror::Error)]
#[error(
"host identity {:?} does not match handle store identity {:?}",
.host_identity.as_str(),
.handle_identity.as_str()
)]
pub struct PluginHostStateMismatch {
host_identity: PluginIdentity,
handle_identity: PluginIdentity,
}
impl PluginHostStateMismatch {
#[must_use]
pub(in crate::plugin) const fn new(
host_identity: PluginIdentity,
handle_identity: PluginIdentity,
) -> Self {
Self {
host_identity,
handle_identity,
}
}
#[must_use]
pub const fn host_identity(&self) -> &PluginIdentity {
&self.host_identity
}
#[must_use]
pub const fn handle_identity(&self) -> &PluginIdentity {
&self.handle_identity
}
}
impl From<PluginHostStateMismatch> for PluginHostImportError {
fn from(source: PluginHostStateMismatch) -> Self {
Self::HostStateMismatch(source)
}
}
impl From<PluginAuthorizationError> for PluginHostImportError {
fn from(source: PluginAuthorizationError) -> Self {
Self::Authorization(source)
}
}
impl From<PluginHandleError> for PluginHostImportError {
fn from(source: PluginHandleError) -> Self {
Self::Handle(source)
}
}
impl From<PluginEffectCommitError> for PluginHostImportError {
fn from(source: PluginEffectCommitError) -> Self {
Self::Effect(source)
}
}
impl From<PluginWorkspaceIoCommitError> for PluginHostImportError {
fn from(source: PluginWorkspaceIoCommitError) -> Self {
Self::WorkspaceIo(source)
}
}
impl From<PluginWorkspaceObserveTaskReserveError> for PluginHostImportError {
fn from(source: PluginWorkspaceObserveTaskReserveError) -> Self {
Self::WorkspaceObserveTask(source)
}
}
impl From<PluginBufferObservationError> for PluginHostImportError {
fn from(source: PluginBufferObservationError) -> Self {
Self::Observation(source)
}
}
impl From<GuestDecodeError> for PluginHostImportError {
fn from(source: GuestDecodeError) -> Self {
Self::Decode(source)
}
}