Skip to main content

fret_runtime/menu/wire/
v2.rs

1use std::sync::Arc;
2
3use crate::CommandId;
4
5use serde::Deserialize;
6
7use super::super::{MenuBarError, MenuItem, MenuRole, SystemMenuType};
8use super::shared::parse_when;
9
10#[derive(Debug, Clone, Deserialize)]
11pub struct MenuBarFileV2 {
12    pub menu_bar_version: u32,
13    pub menus: Vec<MenuFileV2>,
14}
15
16#[derive(Debug, Clone, Deserialize)]
17pub struct MenuFileV2 {
18    pub title: String,
19    #[serde(default)]
20    pub role: Option<MenuRole>,
21    #[serde(default)]
22    pub mnemonic: Option<char>,
23    pub items: Vec<MenuItemFileV2>,
24}
25
26#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
27#[serde(tag = "type", rename_all = "snake_case")]
28pub enum MenuItemFileV2 {
29    Command {
30        command: String,
31        #[serde(default)]
32        when: Option<String>,
33    },
34    Label {
35        title: String,
36    },
37    Separator,
38    Submenu {
39        title: String,
40        #[serde(default)]
41        when: Option<String>,
42        items: Vec<MenuItemFileV2>,
43    },
44    SystemMenu {
45        title: String,
46        #[serde(rename = "system")]
47        menu_type: SystemMenuType,
48    },
49}
50
51impl MenuItemFileV2 {
52    pub(super) fn into_menu_item(self, path: &str) -> Result<MenuItem, MenuBarError> {
53        match self {
54            Self::Separator => Ok(MenuItem::Separator),
55            Self::Command { command, when } => {
56                let when = when
57                    .as_deref()
58                    .map(|w| parse_when(&format!("{path}.when"), w))
59                    .transpose()?;
60                Ok(MenuItem::Command {
61                    command: CommandId::new(command),
62                    when,
63                    toggle: None,
64                })
65            }
66            Self::Label { title } => Ok(MenuItem::Label {
67                title: Arc::from(title),
68            }),
69            Self::Submenu { title, when, items } => {
70                let when = when
71                    .as_deref()
72                    .map(|w| parse_when(&format!("{path}.when"), w))
73                    .transpose()?;
74
75                let mut out_items: Vec<MenuItem> = Vec::with_capacity(items.len());
76                for (idx, item) in items.into_iter().enumerate() {
77                    out_items.push(item.into_menu_item(&format!("{path}.items[{idx}]"))?);
78                }
79
80                Ok(MenuItem::Submenu {
81                    title: Arc::from(title),
82                    when,
83                    items: out_items,
84                })
85            }
86            Self::SystemMenu { title, menu_type } => Ok(MenuItem::SystemMenu {
87                title: Arc::from(title),
88                menu_type,
89            }),
90        }
91    }
92}