1use crate::list_item::ListItem;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Serialize, Deserialize, Debug)]
6pub struct List {
7 list_item_store: HashMap<String, ListItem>,
8 top_level_items: Vec<String>,
9}
10
11impl List {
12 pub fn new() -> List {
13 let list = List {
14 list_item_store: HashMap::new(),
15 top_level_items: Vec::new(),
16 };
17
18 list
19 }
20
21 pub fn from_string(serialized_string: String) -> List {
22 if serialized_string.is_empty() {
23 return List::new();
24 }
25
26 serde_json::from_str(&serialized_string).unwrap()
27 }
28
29 pub fn add_list_item(&mut self, item: ListItem, index: Option<usize>) {
30 self.list_item_store.insert(item.id.clone(), item.clone());
31
32 let insertion_index = match index {
33 Some(index) => index,
34 None => self.top_level_items.len(),
35 };
36
37 self.top_level_items.insert(insertion_index, item.id);
38 }
39
40 pub fn add_existing_child_list_item(
41 &mut self,
42 item_id: &String,
43 parent_id: &String,
44 index: Option<usize>,
45 ) -> Result<(), ListItemTaskError> {
46 let parent = match self.list_item_store.get_mut(parent_id) {
47 Some(parent) => parent,
48 None => {
49 return Err(ListItemTaskError::ParentIdDoesNotExist);
50 }
51 };
52
53 if !parent.children.contains(&item_id) {
54 let insertion_index = match index {
55 Some(index) => index,
56 None => parent.children.len(),
57 };
58
59 parent.children.insert(insertion_index, item_id.clone());
60 } else {
61 return Err(ListItemTaskError::ParentAlreadyHasItem);
62 }
63
64 Ok(())
65 }
66
67 pub fn add_child_list_item(
68 &mut self,
69 item: ListItem,
70 parent_id: &String,
71 index: Option<usize>,
72 ) -> Result<(), ListItemTaskError> {
73 let mut item_does_not_exist: bool = false;
74
75 if !self.list_item_store.contains_key(&item.id) {
77 item_does_not_exist = true;
78 }
79
80 let item_id = item.id.clone();
81
82 if item_does_not_exist {
83 self.list_item_store.insert(item_id.clone(), item);
84 }
85
86 self.add_existing_child_list_item(&item_id, parent_id, index)
87 }
88
89 pub fn get_top_level_list_items(&self) -> Vec<&ListItem> {
90 self.top_level_items
91 .iter()
92 .map(|i| self.list_item_store.get(i).unwrap())
93 .collect()
94 }
95
96 pub fn get_children(&self, item: &ListItem) -> Vec<&ListItem> {
97 item.children
98 .iter()
99 .map(|i| self.list_item_store.get(i).unwrap())
100 .collect()
101 }
102
103 pub fn get_list_item(&self, id: &str) -> Option<&ListItem> {
104 self.list_item_store.get(id)
105 }
106
107 pub fn get_mut_list_item(&mut self, id: &str) -> Option<&mut ListItem> {
108 self.list_item_store.get_mut(id)
109 }
110
111 pub fn remove_list_item(&mut self, id: &str) -> Result<(), ListItemDeletionError> {
112 if self.list_item_store.contains_key(id) {
113 self.list_item_store.remove(id);
114 } else {
115 return Err(ListItemDeletionError::ItemNotExist);
116 }
117
118 for item in self.list_item_store.iter_mut().by_ref() {
119 item.1.children.retain(|c| c != id);
120 }
121
122 Ok(())
123 }
124
125 pub fn remove_child_list_item(
126 &mut self,
127 child_id: &String,
128 parent_id: Option<&String>,
129 ) -> Result<(), ListItemDeletionError> {
130 if !self.list_item_store.contains_key(child_id) {
131 return Err(ListItemDeletionError::ChildDoesNotExist);
132 }
133
134 if let Some(parent_id) = parent_id {
135 if !self.list_item_store.contains_key(parent_id) {
136 return Err(ListItemDeletionError::ParentDoesNotExist);
137 }
138
139 self.get_mut_list_item(&parent_id)
140 .unwrap()
141 .children
142 .retain(|c| c != child_id);
143
144 Ok(())
145 } else {
146 self.top_level_items.retain(|i| i != child_id);
147 Ok(())
148 }
149 }
150
151 pub fn into_string(&self) -> String {
152 serde_json::to_string(&self).unwrap()
153 }
154
155 pub fn get_index_of_child(
156 &self,
157 child_id: &String,
158 parent_id: &String,
159 ) -> Result<usize, ListItemTaskError> {
160 if let Some(parent) = self.get_list_item(&parent_id) {
161 for c in parent.children.iter().enumerate() {
162 if c.1 == child_id {
163 return Ok(c.0);
164 }
165 }
166
167 Err(ListItemTaskError::ChildIdDoesNotExist)
168 } else {
169 Err(ListItemTaskError::ParentIdDoesNotExist)
170 }
171 }
172
173 pub fn get_index_of_top_level_item(
174 &self,
175 child_id: &String,
176 ) -> Result<usize, ListItemTaskError> {
177 for c in self.top_level_items.iter().enumerate() {
178 if c.1 == child_id {
179 return Ok(c.0);
180 }
181 }
182
183 return Err(ListItemTaskError::ChildIdDoesNotExist);
184 }
185}
186
187pub enum ListItemTaskError {
188 ParentAlreadyHasItem,
189 ParentIdDoesNotExist,
190 ChildIdDoesNotExist,
191}
192
193#[derive(Debug)]
194pub enum ListItemDeletionError {
195 ItemNotExist,
196 ChildDoesNotExist,
197 ParentDoesNotExist,
198}