teensy_cms/
menu.rs

1//! Menu and nav utilities.
2use crate::config::Visibility;
3use serde::Serialize;
4
5/// Contains the nested menu items after loading all pages.
6///
7/// When rendered to JSON, it will be an array with items in one of these two formats:
8///
9/// ## Item
10///
11/// ```json
12/// {
13///     "type": "page",
14///     "title": "Some Title",
15///     "url": "/full/path/some-title",
16///     "visibility": "always"
17/// }
18/// ```
19/// ## Menu
20///
21/// ```json
22/// {
23///     "type": "menu",
24///     "title": "Some Menu",
25///     "menu": [ ... ]
26/// }
27/// ```
28#[derive(Serialize, Debug, PartialEq, Eq, Clone)]
29pub struct Menu(pub(crate) Vec<MenuItem>);
30
31impl Menu {
32    /// An iterator over the [`MenuItem`]s.
33    pub fn iter(&self) -> impl Iterator<Item = &MenuItem> {
34        self.0.iter()
35    }
36}
37
38/// A menu item.
39///
40/// For JSON representation, see [`Menu`].
41#[derive(Serialize, Debug, PartialEq, Eq, Clone)]
42#[serde(tag = "type", rename_all = "lowercase")]
43pub enum MenuItem {
44    /// A single, clickable menu item.
45    Page {
46        /// The menu item's title.
47        title: String,
48        /// The full URL.
49        url: String,
50        /// The page's visibility. See [`crate::config::Visibility`] for more information.
51        visibility: Visibility,
52    },
53    /// A menu with a title and nested items.
54    Menu {
55        /// The menu item's title.
56        title: String,
57        /// The nested submenu.
58        menu: Menu,
59    },
60}
61
62impl MenuItem {
63    /// Helper function to access the title of the two variants.
64    pub fn title(&self) -> &str {
65        match self {
66            Self::Page { title, .. } => title,
67            Self::Menu { title, .. } => title,
68        }
69    }
70}