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}