shared/domain/module/body/
cover.rs1use crate::domain::module::{
2 body::{Body, BodyConvert, BodyExt, StepExt, ThemeId, _groups::design::*},
3 ModuleKind,
4};
5use serde::{de::IntoDeserializer, Deserialize, Serialize};
6use std::collections::HashSet;
7
8use super::Audio;
9
10#[derive(Clone, Serialize, Deserialize, Debug, Default)]
12pub struct ModuleData {
13 pub content: Option<Content>,
15}
16
17impl BodyExt<(), Step> for ModuleData {
18 fn as_body(&self) -> Body {
19 Body::Cover(self.clone())
20 }
21
22 fn is_complete(&self) -> bool {
23 self.content.is_some()
24 }
25
26 fn kind() -> ModuleKind {
27 ModuleKind::Cover
28 }
29
30 fn new_with_mode_and_theme(_mode: (), theme: ThemeId) -> Self {
31 ModuleData {
32 content: Some(Content {
33 base: BaseContent {
34 theme,
35 ..Default::default()
36 },
37 ..Default::default()
38 }),
39 ..Default::default()
40 }
41 }
42
43 fn mode(&self) -> Option<()> {
44 None
45 }
46
47 fn requires_choose_mode(&self) -> bool {
48 false
49 }
50
51 fn set_editor_state_step(&mut self, step: Step) {
52 if let Some(content) = self.content.as_mut() {
53 content.editor_state.step = step;
54 }
55 }
56 fn set_editor_state_steps_completed(&mut self, steps_completed: HashSet<Step>) {
57 if let Some(content) = self.content.as_mut() {
58 content.editor_state.steps_completed = steps_completed;
59 }
60 }
61
62 fn get_editor_state_step(&self) -> Option<Step> {
63 self.content
64 .as_ref()
65 .map(|content| content.editor_state.step)
66 }
67
68 fn get_editor_state_steps_completed(&self) -> Option<HashSet<Step>> {
69 self.content
70 .as_ref()
71 .map(|content| content.editor_state.steps_completed.clone())
72 }
73
74 fn set_theme(&mut self, theme_id: ThemeId) {
75 if let Some(content) = self.content.as_mut() {
76 content.base.theme = theme_id;
77 }
78 }
79
80 fn get_theme(&self) -> Option<ThemeId> {
81 self.content.as_ref().map(|content| content.base.theme)
82 }
83}
84
85impl BodyConvert for ModuleData {}
86
87impl TryFrom<Body> for ModuleData {
88 type Error = &'static str;
89
90 fn try_from(body: Body) -> Result<Self, Self::Error> {
91 match body {
92 Body::Cover(data) => Ok(data),
93 _ => Err("cannot convert body to cover!"),
94 }
95 }
96}
97
98#[derive(Default, Clone, Serialize, Deserialize, Debug)]
100pub struct Content {
101 pub editor_state: EditorState,
103 pub base: BaseContent,
105 #[serde(default)]
107 pub audio: Option<Audio>,
108 #[serde(default)]
110 pub play_settings: PlaySettings,
111}
112
113#[derive(Default, Clone, Serialize, Deserialize, Debug)]
115pub struct EditorState {
116 pub step: Step,
118
119 pub steps_completed: HashSet<Step>,
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
130#[serde(remote = "Step")]
131pub enum Step {
132 One,
134 Two,
136 Three,
138 Four,
140}
141
142impl<'de> Deserialize<'de> for Step {
143 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144 where
145 D: serde::Deserializer<'de>,
146 {
147 let value = String::deserialize(deserializer)?;
148 if value == "Four" {
149 Ok(Self::Three)
150 } else {
151 Step::deserialize(value.into_deserializer())
152 }
153 }
154}
155
156impl Serialize for Step {
157 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
158 where
159 S: serde::Serializer,
160 {
161 Step::serialize(&self, serializer)
162 }
163}
164
165impl Default for Step {
166 fn default() -> Self {
167 Self::One
168 }
169}
170
171impl StepExt for Step {
172 fn next(&self) -> Option<Self> {
173 match self {
174 Self::One => Some(Self::Two),
175 Self::Two => Some(Self::Three),
176 Self::Three => Some(Self::Four),
177 Self::Four => None,
178 }
179 }
180
181 fn as_number(&self) -> usize {
182 match self {
183 Self::One => 1,
184 Self::Two => 2,
185 Self::Three => 3,
186 Self::Four => 4,
187 }
188 }
189
190 fn label(&self) -> &'static str {
191 const STR_DESIGN: &'static str = "Design";
192 const STR_CONTENT: &'static str = "Content";
193 const STR_SETTINGS: &'static str = "Settings";
194 const STR_PREVIEW: &'static str = "Preview";
195
196 match self {
197 Self::One => STR_DESIGN,
198 Self::Two => STR_CONTENT,
199 Self::Three => STR_SETTINGS,
200 Self::Four => STR_PREVIEW,
201 }
202 }
203
204 fn get_list() -> Vec<Self> {
205 vec![Self::One, Self::Two, Self::Three, Self::Four]
206 }
207 fn get_preview() -> Self {
208 Self::Four
209 }
210}
211
212#[derive(Clone, Default, Serialize, Deserialize, Debug)]
214pub struct PlaySettings {
215 pub next: Next,
217}
218
219#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
221pub enum Next {
222 Auto,
224 AfterAudio,
226 ClickNext,
228}
229
230impl Default for Next {
231 fn default() -> Self {
232 Self::Auto
233 }
234}