aga 2.0.0

AgenticGraphicsAcceleration — standalone agentic-first GPU rendering backend; wgpu replacement with Vulkan, OpenGL, and complete ontology
Documentation
//! Widget capabilities that advertise interaction affordances.

use serde::{Deserialize, Serialize};

/// A capability that a widget instance advertises.
///
/// Agents query capabilities to understand what interactions are possible
/// with a given widget without trial-and-error.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum AgentCapability {
    /// Widget can receive keyboard focus.
    Focusable,
    /// Widget responds to mouse clicks.
    Clickable,
    /// Widget can be scrolled (vertical, horizontal, or both).
    Scrollable { vertical: bool, horizontal: bool },
    /// Widget accepts text input.
    TextInput {
        multiline: bool,
        max_length: Option<usize>,
    },
    /// Widget supports item selection (single or multi).
    Selectable {
        multi_select: bool,
        item_count: usize,
    },
    /// Widget can be expanded or collapsed.
    Expandable { expanded: bool },
    /// Widget supports drag-and-drop as a source.
    Draggable,
    /// Widget acts as a drop target.
    DropTarget,
    /// Widget supports resizing by the user.
    Resizable {
        min_width: Option<f32>,
        min_height: Option<f32>,
        max_width: Option<f32>,
        max_height: Option<f32>,
    },
    /// Widget has an animation in progress.
    Animated { playing: bool },
    /// Widget supports value editing within a range.
    RangeEditable {
        min: f64,
        max: f64,
        step: Option<f64>,
    },
    /// Widget can be toggled on/off.
    Toggleable { state: bool },
    /// Widget supports sorting.
    Sortable { columns: Vec<String> },
    /// Widget supports filtering.
    Filterable,
    /// Widget supports search.
    Searchable,
    /// Widget supports copy-to-clipboard.
    Copyable,
    /// Widget provides hover tooltips.
    HasTooltip,
    /// Widget supports keyboard shortcuts.
    HasKeyBindings { bindings: Vec<(String, String)> },
    /// Widget can be minimized.
    Minimizable,
    /// Widget can be maximized.
    Maximizable,
    /// Widget can be closed.
    Closable,
    /// Widget supports pinch-to-zoom.
    Zoomable { min_zoom: f32, max_zoom: f32 },
    /// Custom capability with a name tag.
    Custom(String),
}

impl AgentCapability {
    /// Returns the canonical name of this capability for querying.
    pub fn name(&self) -> &str {
        match self {
            Self::Focusable => "focusable",
            Self::Clickable => "clickable",
            Self::Scrollable { .. } => "scrollable",
            Self::TextInput { .. } => "text-input",
            Self::Selectable { .. } => "selectable",
            Self::Expandable { .. } => "expandable",
            Self::Draggable => "draggable",
            Self::DropTarget => "drop-target",
            Self::Resizable { .. } => "resizable",
            Self::Animated { .. } => "animated",
            Self::RangeEditable { .. } => "range-editable",
            Self::Toggleable { .. } => "toggleable",
            Self::Sortable { .. } => "sortable",
            Self::Filterable => "filterable",
            Self::Searchable => "searchable",
            Self::Copyable => "copyable",
            Self::HasTooltip => "has-tooltip",
            Self::HasKeyBindings { .. } => "has-key-bindings",
            Self::Minimizable => "minimizable",
            Self::Maximizable => "maximizable",
            Self::Closable => "closable",
            Self::Zoomable { .. } => "zoomable",
            Self::Custom(name) => name.as_str(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn capability_names() {
        assert_eq!(AgentCapability::Focusable.name(), "focusable");
        assert_eq!(AgentCapability::Clickable.name(), "clickable");
        assert_eq!(
            AgentCapability::Scrollable {
                vertical: true,
                horizontal: false
            }
            .name(),
            "scrollable"
        );
        assert_eq!(
            AgentCapability::TextInput {
                multiline: false,
                max_length: None
            }
            .name(),
            "text-input"
        );
        assert_eq!(AgentCapability::Draggable.name(), "draggable");
        assert_eq!(AgentCapability::DropTarget.name(), "drop-target");
        assert_eq!(AgentCapability::Custom("my-cap".into()).name(), "my-cap");
    }

    #[test]
    fn capability_serialize_roundtrip() {
        let caps = vec![
            AgentCapability::Focusable,
            AgentCapability::Clickable,
            AgentCapability::Toggleable { state: true },
            AgentCapability::RangeEditable {
                min: 0.0,
                max: 100.0,
                step: Some(1.0),
            },
            AgentCapability::Custom("special".into()),
        ];
        for cap in caps {
            let json = serde_json::to_string(&cap).unwrap();
            let cap2: AgentCapability = serde_json::from_str(&json).unwrap();
            assert_eq!(cap, cap2);
        }
    }
}