use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use ts_rs::TS;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct MenuContext {
states: HashMap<String, bool>,
}
impl MenuContext {
pub fn new() -> Self {
Self {
states: HashMap::new(),
}
}
pub fn set(&mut self, name: impl Into<String>, value: bool) -> &mut Self {
self.states.insert(name.into(), value);
self
}
pub fn get(&self, name: &str) -> bool {
self.states.get(name).copied().unwrap_or(false)
}
pub fn with(mut self, name: impl Into<String>, value: bool) -> Self {
self.set(name, value);
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, TS)]
#[ts(export)]
#[serde(untagged)]
pub enum MenuItem {
Separator { separator: bool },
Action {
label: String,
action: String,
#[serde(default)]
#[ts(type = "Record<string, any>")]
args: HashMap<String, serde_json::Value>,
#[serde(default)]
when: Option<String>,
#[serde(default)]
checkbox: Option<String>,
},
Submenu { label: String, items: Vec<Self> },
DynamicSubmenu { label: String, source: String },
Label { info: String },
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema, PartialEq, Eq, TS)]
#[ts(export)]
pub struct Menu {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub label: String,
pub items: Vec<MenuItem>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub when: Option<String>,
}