use crate::plugin::{
PluginBufferHandle, PluginHandleKind, PluginHostImportError, PluginHostResourceKind,
PluginResourceHandleRejectionReason, PluginViewHandle,
};
use wasmtime::component::{Resource, ResourceTable, ResourceTableError};
#[derive(Clone, Copy, Debug)]
pub(super) struct WasmtimeUpdateResources {
view: WasmtimeUpdateViewResource,
buffer: WasmtimeUpdateBufferResource,
}
impl WasmtimeUpdateResources {
pub(super) const fn new(
view: WasmtimeUpdateViewResource,
buffer: WasmtimeUpdateBufferResource,
) -> Self {
Self { view, buffer }
}
pub(super) fn view_borrow(self) -> Resource<PluginViewHandle> {
self.view.borrow()
}
pub(super) fn buffer_borrow(self) -> Resource<PluginBufferHandle> {
self.buffer.borrow()
}
pub(super) fn borrows(self) -> WasmtimeUpdateResourceBorrows {
WasmtimeUpdateResourceBorrows {
view: self.view_borrow(),
buffer: self.buffer_borrow(),
}
}
pub(super) fn delete_from(
self,
table: &mut ResourceTable,
) -> Result<(), PluginHostImportError> {
let view = delete_update_resource(table, self.view.owned(), PluginHandleKind::View);
let buffer = delete_update_resource(table, self.buffer.owned(), PluginHandleKind::Buffer);
view?;
buffer
}
}
pub(super) struct WasmtimeUpdateResourceBorrows {
pub(super) view: Resource<PluginViewHandle>,
pub(super) buffer: Resource<PluginBufferHandle>,
}
#[derive(Clone, Copy, Debug)]
pub(super) struct WasmtimeUpdateViewResource {
pub(super) rep: u32,
}
impl WasmtimeUpdateViewResource {
pub(super) fn from_owned(resource: &Resource<PluginViewHandle>) -> Self {
Self {
rep: resource.rep(),
}
}
pub(super) fn borrow(self) -> Resource<PluginViewHandle> {
Resource::new_borrow(self.rep)
}
pub(super) fn owned(self) -> Resource<PluginViewHandle> {
Resource::new_own(self.rep)
}
}
#[derive(Clone, Copy, Debug)]
pub(super) struct WasmtimeUpdateBufferResource {
pub(super) rep: u32,
}
impl WasmtimeUpdateBufferResource {
pub(super) fn from_owned(resource: &Resource<PluginBufferHandle>) -> Self {
Self {
rep: resource.rep(),
}
}
pub(super) fn borrow(self) -> Resource<PluginBufferHandle> {
Resource::new_borrow(self.rep)
}
pub(super) fn owned(self) -> Resource<PluginBufferHandle> {
Resource::new_own(self.rep)
}
}
pub(super) fn delete_update_resource<T: 'static>(
table: &mut ResourceTable,
resource: Resource<T>,
kind: PluginHandleKind,
) -> Result<(), PluginHostImportError> {
match table.delete(resource) {
Ok(_value) => Ok(()),
Err(ResourceTableError::NotPresent) => Ok(()),
Err(source) => Err(resource_handle_error(kind.into(), &source)),
}
}
pub(super) const fn resource_handle_error(
kind: PluginHostResourceKind,
source: &ResourceTableError,
) -> PluginHostImportError {
let reason = match source {
ResourceTableError::NotPresent => PluginResourceHandleRejectionReason::Missing,
ResourceTableError::WrongType => PluginResourceHandleRejectionReason::WrongType,
ResourceTableError::Full | ResourceTableError::HasChildren => {
PluginResourceHandleRejectionReason::Unavailable
}
};
PluginHostImportError::ResourceHandle { kind, reason }
}
pub(super) const fn workspace_observe_task_resource_error(
source: &ResourceTableError,
) -> PluginHostImportError {
resource_handle_error(PluginHostResourceKind::WorkspaceObserveTask, source)
}
pub(super) const fn workspace_observe_task_resource_unavailable() -> PluginHostImportError {
PluginHostImportError::ResourceHandle {
kind: PluginHostResourceKind::WorkspaceObserveTask,
reason: PluginResourceHandleRejectionReason::Unavailable,
}
}