alma 0.1.1

A Bevy-native modal text editor with Vim-style navigation.
Documentation
//! Wasmtime component bindings.

wasmtime::component::bindgen!({
    path: "wit",
    world: "plugin",
    with: {
        "alma:editor/host.buffer-handle": crate::plugin::PluginBufferHandle,
        "alma:editor/host.view-handle": crate::plugin::PluginViewHandle,
        "alma:editor/host.workspace-observe-task": crate::plugin::PluginWorkspaceObserveTaskHandle,
    },
    imports: { default: trappable },
});

use super::WitCapability;

/// Returns the generated WIT capability vocabulary converted into Alma's stable type.
#[must_use]
pub const fn generated_capabilities() -> [WitCapability; 5] {
    [
        wit_capability_to_alma(alma::editor::host::Capability::BufferObserve),
        wit_capability_to_alma(alma::editor::host::Capability::BufferProposeEdit),
        wit_capability_to_alma(alma::editor::host::Capability::WorkspaceObserve),
        wit_capability_to_alma(alma::editor::host::Capability::WorkspaceArtifactWrite),
        wit_capability_to_alma(alma::editor::host::Capability::StatusPublish),
    ]
}

/// Converts generated WIT capability variants into Alma's host authorization vocabulary.
const fn wit_capability_to_alma(capability: alma::editor::host::Capability) -> WitCapability {
    match capability {
        alma::editor::host::Capability::BufferObserve => WitCapability::BufferObserve,
        alma::editor::host::Capability::BufferProposeEdit => WitCapability::BufferProposeEdit,
        alma::editor::host::Capability::WorkspaceObserve => WitCapability::WorkspaceObserve,
        alma::editor::host::Capability::WorkspaceArtifactWrite => {
            WitCapability::WorkspaceArtifactWrite
        }
        alma::editor::host::Capability::StatusPublish => WitCapability::StatusPublish,
    }
}

#[cfg(test)]
mod tests {
    use super::generated_capabilities;
    use crate::plugin::{PluginCapabilityRef, WitCapability, WitCapabilityRefError};

    #[test]
    fn generated_wit_resources_match_handle_vocabulary() {
        assert!(
            std::any::type_name::<super::alma::editor::host::BufferHandle>()
                .ends_with("BufferHandle")
        );
        assert!(
            std::any::type_name::<super::alma::editor::host::ViewHandle>().ends_with("ViewHandle")
        );
        assert!(
            std::any::type_name::<super::alma::editor::host::WorkspaceObserveTask>()
                .contains("WorkspaceObserveTask")
        );
    }

    #[test]
    fn generated_wit_capabilities_match_alma_vocabulary() {
        assert_eq!(generated_capabilities(), WitCapability::all());
    }

    #[test]
    fn generated_wit_capabilities_map_to_authorization_refs() {
        for capability in generated_capabilities() {
            match capability {
                WitCapability::BufferObserve => {
                    assert_eq!(
                        capability.as_ref(None),
                        Ok(PluginCapabilityRef::BufferObserve)
                    );
                }
                WitCapability::BufferProposeEdit => {
                    assert_eq!(
                        capability.as_ref(None),
                        Ok(PluginCapabilityRef::BufferProposeEdit)
                    );
                }
                WitCapability::StatusPublish => {
                    assert_eq!(
                        capability.as_ref(None),
                        Ok(PluginCapabilityRef::StatusPublish)
                    );
                }
                WitCapability::WorkspaceObserve => {
                    assert!(matches!(
                        capability.as_ref(None),
                        Err(WitCapabilityRefError::MissingPath { .. })
                    ));
                    assert!(matches!(
                        capability.as_ref(Some("docs/arch.md")),
                        Ok(PluginCapabilityRef::WorkspaceObserve(_))
                    ));
                }
                WitCapability::WorkspaceArtifactWrite => {
                    assert!(matches!(
                        capability.as_ref(None),
                        Err(WitCapabilityRefError::MissingPath { .. })
                    ));
                    assert!(matches!(
                        capability.as_ref(Some("docs/arch.md")),
                        Ok(PluginCapabilityRef::WorkspaceArtifactWrite(_))
                    ));
                }
            }
        }
    }
}