shared/domain/module/body/
resource_cover.rs1use crate::domain::module::{
2 body::{Body, BodyConvert, BodyExt, StepExt, ThemeId, _groups::design::*},
3 ModuleKind,
4};
5use serde::{Deserialize, Serialize};
6use std::collections::HashSet;
7
8#[derive(Clone, Serialize, Deserialize, Debug)]
10pub struct ModuleData {
11 pub content: Option<Content>,
13}
14
15impl Default for ModuleData {
17 fn default() -> Self {
18 Self {
19 content: Some(Content::default()),
20 }
21 }
22}
23
24impl BodyExt<(), Step> for ModuleData {
25 fn as_body(&self) -> Body {
26 Body::ResourceCover(self.clone())
27 }
28
29 fn is_complete(&self) -> bool {
30 self.content.is_some()
31 }
32
33 fn kind() -> ModuleKind {
34 ModuleKind::ResourceCover
35 }
36
37 fn new_with_mode_and_theme(_mode: (), _theme_id: ThemeId) -> Self {
38 ModuleData {
39 content: Some(Content::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::ResourceCover(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
104 pub base: BaseContent,
106}
107
108#[derive(Default, Clone, Serialize, Deserialize, Debug)]
110pub struct EditorState {
111 pub step: Step,
113
114 pub steps_completed: HashSet<Step>,
116}
117
118#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
120pub enum Step {
121 One,
123 Two,
125 Three,
127}
128
129impl Default for Step {
130 fn default() -> Self {
131 Self::One
132 }
133}
134
135impl StepExt for Step {
136 fn next(&self) -> Option<Self> {
137 match self {
138 Self::One => Some(Self::Two),
139 Self::Two => Some(Self::Three),
140 Self::Three => None,
141 }
142 }
143
144 fn as_number(&self) -> usize {
145 match self {
146 Self::One => 1,
147 Self::Two => 2,
148 Self::Three => 3,
149 }
150 }
151
152 fn label(&self) -> &'static str {
153 const STR_DESIGN: &'static str = "Design";
154 const STR_CONTENT: &'static str = "Content";
155 const STR_PREVIEW: &'static str = "Preview";
156
157 match self {
158 Self::One => STR_DESIGN,
159 Self::Two => STR_CONTENT,
160 Self::Three => STR_PREVIEW,
161 }
162 }
163
164 fn get_list() -> Vec<Self> {
165 vec![Self::One, Self::Two, Self::Three]
166 }
167 fn get_preview() -> Self {
168 Self::Three
169 }
170}