shared/domain/module/body/
memory.rs1use crate::domain::module::{
2 body::{Body, BodyConvert, BodyExt, ThemeId, _groups::cards::*},
3 ModuleKind,
4};
5use serde::{Deserialize, Serialize};
6use std::collections::HashSet;
7
8#[derive(Default, Clone, Serialize, Deserialize, Debug)]
10pub struct ModuleData {
11 pub content: Option<Content>,
13}
14
15#[derive(Default, Clone, Serialize, Deserialize, Debug)]
17pub struct Content {
18 pub base: BaseContent,
20 pub player_settings: PlayerSettings,
22}
23
24#[derive(Default, Clone, Serialize, Deserialize, Debug)]
26pub struct PlayerSettings {
27 pub time_limit: Option<u32>,
29 pub pairs_to_display: Option<u32>,
31}
32
33impl BodyExt<Mode, Step> for ModuleData {
34 fn as_body(&self) -> Body {
35 Body::MemoryGame(self.clone())
36 }
37
38 fn is_complete(&self) -> bool {
39 self.content
40 .as_ref()
41 .map_or(false, |content| content.base.is_valid())
42 }
43
44 fn kind() -> ModuleKind {
45 ModuleKind::Memory
46 }
47
48 fn new_with_mode_and_theme(mode: Mode, theme: ThemeId) -> Self {
49 ModuleData {
50 content: Some(Content {
51 base: BaseContent {
52 mode,
53 theme,
54 ..Default::default()
55 },
56 ..Default::default()
57 }),
58 }
59 }
60
61 fn mode(&self) -> Option<Mode> {
62 self.content.as_ref().map(|c| c.base.mode.clone())
63 }
64
65 fn requires_choose_mode(&self) -> bool {
66 self.content.is_none()
67 }
68
69 fn set_editor_state_step(&mut self, step: Step) {
70 if let Some(content) = self.content.as_mut() {
71 content.base.editor_state.step = step;
72 }
73 }
74 fn set_editor_state_steps_completed(&mut self, steps_completed: HashSet<Step>) {
75 if let Some(content) = self.content.as_mut() {
76 content.base.editor_state.steps_completed = steps_completed;
77 }
78 }
79
80 fn get_editor_state_step(&self) -> Option<Step> {
81 self.content
82 .as_ref()
83 .map(|content| content.base.editor_state.step)
84 }
85
86 fn get_editor_state_steps_completed(&self) -> Option<HashSet<Step>> {
87 self.content
88 .as_ref()
89 .map(|content| content.base.editor_state.steps_completed.clone())
90 }
91
92 fn set_theme(&mut self, theme_id: ThemeId) {
93 if let Some(content) = self.content.as_mut() {
94 content.base.theme = theme_id;
95 }
96 }
97
98 fn get_theme(&self) -> Option<ThemeId> {
99 self.content.as_ref().map(|content| content.base.theme)
100 }
101}
102
103impl BodyConvert for ModuleData {
104 fn convertable_list() -> Vec<ModuleKind> {
105 vec![
106 ModuleKind::Matching,
107 ModuleKind::Flashcards,
108 ModuleKind::CardQuiz,
109 ]
110 }
111 fn convert_to_matching(&self) -> Result<super::matching::ModuleData, &'static str> {
112 Ok(super::matching::ModuleData {
113 content: self
114 .content
115 .as_ref()
116 .map(|content| super::matching::Content {
117 base: content.base.clone(),
118 player_settings: super::matching::PlayerSettings::default(),
119 }),
120 })
121 }
122 fn convert_to_flashcards(&self) -> Result<super::flashcards::ModuleData, &'static str> {
123 Ok(super::flashcards::ModuleData {
124 content: self
125 .content
126 .as_ref()
127 .map(|content| super::flashcards::Content {
128 base: content.base.clone(),
129 player_settings: super::flashcards::PlayerSettings::default(),
130 }),
131 })
132 }
133
134 fn convert_to_card_quiz(&self) -> Result<super::card_quiz::ModuleData, &'static str> {
135 Ok(super::card_quiz::ModuleData {
136 content: self
137 .content
138 .as_ref()
139 .map(|content| super::card_quiz::Content {
140 base: content.base.clone(),
141 player_settings: super::card_quiz::PlayerSettings::default(),
142 }),
143 })
144 }
145}
146
147impl TryFrom<Body> for ModuleData {
148 type Error = &'static str;
149
150 fn try_from(body: Body) -> Result<Self, Self::Error> {
151 match body {
152 Body::MemoryGame(data) => Ok(data),
153 _ => Err("cannot convert body to memory game!"),
154 }
155 }
156}