1#![allow(clippy::module_name_repetitions)]
2use crate::widget::{empty, BackButton, Widget};
3use serde::{Deserialize, Serialize};
4
5#[allow(clippy::large_enum_variant)]
6#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
7#[serde(tag = "typ")]
8pub enum Page {
9 #[serde(rename = "nav_page")]
10 Nav(NavPage),
11 #[serde(rename = "plain_page")]
12 Plain(PlainPage),
13}
14
15impl From<NavPage> for Page {
16 fn from(value: NavPage) -> Self {
17 Page::Nav(value)
18 }
19}
20
21impl From<PlainPage> for Page {
22 fn from(value: PlainPage) -> Self {
23 Page::Plain(value)
24 }
25}
26
27#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
28pub struct NavPage {
29 #[serde(default, skip_serializing_if = "Option::is_none")]
30 pub end: Option<Widget>,
31 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
32 pub ephemeral: bool,
33 #[serde(default, skip_serializing_if = "String::is_empty")]
34 pub id: String,
35 #[serde(default, skip_serializing_if = "crate::is_default")]
36 pub poll_seconds: u32,
37 #[serde(default, skip_serializing_if = "Option::is_none")]
38 pub start: Option<Widget>,
39 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
40 pub stream: bool,
41 #[serde(default)]
42 pub title: String,
43 pub widget: Widget,
44}
45
46impl NavPage {
47 #[must_use]
48 pub fn new(title: impl Into<String>, widget: impl Into<Widget>) -> Self {
49 Self {
50 end: None,
51 ephemeral: false,
52 id: String::new(),
53 poll_seconds: 0,
54 start: None,
55 stream: false,
56 title: title.into(),
57 widget: widget.into(),
58 }
59 }
60
61 #[must_use]
62 pub fn without_back(mut self) -> Self {
63 self.start = Some(empty().into());
64 self
65 }
66
67 #[must_use]
68 pub fn with_end(mut self, widget: impl Into<Widget>) -> Self {
69 self.end = Some(widget.into());
70 self
71 }
72
73 #[must_use]
74 pub fn with_ephemeral(mut self, ephemeral: bool) -> Self {
75 self.ephemeral = ephemeral;
76 self
77 }
78
79 #[must_use]
80 pub fn with_id(mut self, id: impl AsRef<str>) -> Self {
81 self.id = id.as_ref().to_string();
82 self
83 }
84
85 #[must_use]
86 pub fn with_poll(mut self, seconds: u32) -> Self {
87 self.poll_seconds = seconds;
88 self
89 }
90
91 #[must_use]
92 pub fn with_start(mut self, back_button: BackButton) -> Self {
93 self.start = Some(back_button.into());
94 self
95 }
96
97 #[must_use]
98 pub fn with_empty_start(mut self) -> Self {
99 self.start = Some(empty().into());
100 self
101 }
102
103 #[must_use]
104 pub fn with_stream(mut self) -> Self {
105 self.stream = true;
106 self
107 }
108}
109
110pub fn nav_page(title: impl Into<String>, widget: impl Into<Widget>) -> NavPage {
111 NavPage::new(title, widget)
112}
113
114#[derive(Clone, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
115pub struct PlainPage {
116 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
117 pub ephemeral: bool,
118 #[serde(default, skip_serializing_if = "String::is_empty")]
119 pub id: String,
120 #[serde(default, skip_serializing_if = "crate::is_default")]
121 pub poll_seconds: u32,
122 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
123 pub stream: bool,
124 #[serde(default)]
125 pub title: String,
126 pub widget: Widget,
127}
128
129impl PlainPage {
130 #[must_use]
131 pub fn new(title: impl Into<String>, widget: impl Into<Widget>) -> Self {
132 Self {
133 ephemeral: false,
134 id: String::new(),
135 poll_seconds: 0,
136 stream: false,
137 title: title.into(),
138 widget: widget.into(),
139 }
140 }
141
142 #[must_use]
143 pub fn with_ephemeral(mut self, ephemeral: bool) -> Self {
144 self.ephemeral = ephemeral;
145 self
146 }
147
148 #[must_use]
149 pub fn with_id(mut self, id: impl AsRef<str>) -> Self {
150 self.id = id.as_ref().to_string();
151 self
152 }
153
154 #[must_use]
155 pub fn with_poll(mut self, seconds: u32) -> Self {
156 self.poll_seconds = seconds;
157 self
158 }
159
160 #[must_use]
161 pub fn with_stream(mut self) -> Self {
162 self.stream = true;
163 self
164 }
165}
166
167pub fn plain_page(title: impl Into<String>, widget: impl Into<Widget>) -> PlainPage {
168 PlainPage::new(title, widget)
169}