alma 0.1.1

A Bevy-native modal text editor with Vim-style navigation.
Documentation
//! Host-import resource authority vocabulary.

use super::super::{PluginHandleKind, PluginWorkspaceObserveTaskHandle};
use crate::plugin::WorkspacePath;
use std::fmt::{Debug, Display, Formatter};

/// Host-session proof for a guest-visible workspace observation task resource.
///
/// The handle and revalidation path are produced together at the authorization boundary. Runtime
/// adapters should carry this proof into their resource table instead of reconstructing path
/// authority from parallel local state.
pub(in crate::plugin) struct PluginWorkspaceObserveTaskResourceAuthority {
    /// Identity-scoped task handle reserved for the guest.
    handle: PluginWorkspaceObserveTaskHandle,
    /// Workspace path that authorized the task resource.
    authority_path: WorkspacePath,
}

/// Task-resource authority split by the runtime resource-table boundary.
pub(in crate::plugin) struct PluginWorkspaceObserveTaskResourceAuthorityParts {
    /// Identity-scoped task handle reserved for the guest.
    pub handle: PluginWorkspaceObserveTaskHandle,
    /// Workspace path that authorized the task resource.
    pub authority_path: WorkspacePath,
}

impl PluginWorkspaceObserveTaskResourceAuthority {
    /// Creates task-resource authority from the host-session authorization boundary.
    pub(super) const fn new(
        handle: PluginWorkspaceObserveTaskHandle,
        authority_path: WorkspacePath,
    ) -> Self {
        Self {
            handle,
            authority_path,
        }
    }

    /// Returns the reserved task handle.
    #[must_use]
    #[cfg(test)]
    pub(in crate::plugin) const fn handle(&self) -> &PluginWorkspaceObserveTaskHandle {
        &self.handle
    }

    /// Splits the proof into the pieces retained by the runtime resource table.
    #[must_use]
    pub(in crate::plugin) fn into_parts(self) -> PluginWorkspaceObserveTaskResourceAuthorityParts {
        PluginWorkspaceObserveTaskResourceAuthorityParts {
            handle: self.handle,
            authority_path: self.authority_path,
        }
    }

    /// Builds authority for focused runtime resource tests.
    #[cfg(test)]
    pub(in crate::plugin) const fn for_test(
        handle: PluginWorkspaceObserveTaskHandle,
        authority_path: WorkspacePath,
    ) -> Self {
        Self {
            handle,
            authority_path,
        }
    }
}

impl Debug for PluginWorkspaceObserveTaskResourceAuthority {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        formatter
            .debug_struct("PluginWorkspaceObserveTaskResourceAuthority")
            .field("handle", &self.handle)
            .field("authority_path", &self.authority_path)
            .finish()
    }
}

/// Component-model resource rejection shape.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PluginHostResourceKind {
    /// Borrowed `view-handle` resource.
    ViewHandle,
    /// Borrowed `buffer-handle` resource.
    BufferHandle,
    /// Host-owned `workspace-observe-task` resource.
    WorkspaceObserveTask,
}

impl PluginHostResourceKind {
    /// Stable redacted resource kind text.
    #[must_use]
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::ViewHandle => "view",
            Self::BufferHandle => "buffer",
            Self::WorkspaceObserveTask => "workspace-observe-task",
        }
    }
}

impl From<PluginHandleKind> for PluginHostResourceKind {
    fn from(kind: PluginHandleKind) -> Self {
        match kind {
            PluginHandleKind::View => Self::ViewHandle,
            PluginHandleKind::Buffer => Self::BufferHandle,
        }
    }
}

impl Display for PluginHostResourceKind {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        formatter.write_str(self.as_str())
    }
}

/// Component-model resource rejection shape.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PluginResourceHandleRejectionReason {
    /// The resource table has no live record.
    Missing,
    /// The table record has the wrong host type.
    WrongType,
    /// The table rejected the resource for another bounded reason.
    Unavailable,
}

impl PluginResourceHandleRejectionReason {
    /// Stable redacted resource rejection text.
    #[must_use]
    pub const fn as_str(self) -> &'static str {
        match self {
            Self::Missing => "missing",
            Self::WrongType => "wrong-type",
            Self::Unavailable => "unavailable",
        }
    }
}

impl Display for PluginResourceHandleRejectionReason {
    fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
        formatter.write_str(self.as_str())
    }
}