Skip to main content

just_lists_core/
list.rs

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        // check if item already exists
76        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}