rust_ds/linked_lists/singly/
mod.rs

1use super::SNode as Node;
2use super::{Error, Result};
3use std::fmt::Debug;
4
5/// `Singly` is a singly linked list that contains a reference to the head node and the length of the list.
6#[derive(Debug)]
7pub struct Singly<T> {
8    head: Option<Box<Node<T>>>,
9    len: usize,
10}
11
12impl<T> Default for Singly<T>
13where
14    T: Debug + PartialEq + Clone,
15{
16    fn default() -> Self {
17        Self::new()
18    }
19}
20
21impl<T> Singly<T>
22where
23    T: Debug + PartialEq + Clone,
24{
25    /// Creates a new `Singly` list.
26    pub fn new() -> Self {
27        Singly { head: None, len: 0 }
28    }
29    /// Append a new value to the end of the list.
30    pub fn append(&mut self, value: T) {
31        let new_node = Box::new(Node::new(value));
32
33        match self.head.as_mut() {
34            None => {
35                self.head = Some(new_node);
36            }
37            Some(mut current) => {
38                while current.get_next().is_some() {
39                    current = current.get_next_mut().as_mut().unwrap();
40                }
41                current.set_next(Some(new_node));
42            }
43        }
44        self.len += 1;
45    }
46    /// Remove a node from the list.
47    /// Returns true if the value is found and removed.
48    /// If the value is not found, it returns an error.
49    pub fn remove(&mut self, value: T) -> Result<bool> {
50        if self.is_empty() {
51            return Err(Error::EmptyList);
52        }
53
54        match self.head.as_mut() {
55            None => return Err(Error::EmptyList),
56            Some(mut current) => {
57                if *current.get_value() == value {
58                    self.head = current.get_next_mut().take();
59                    self.len -= 1;
60                    return Ok(true);
61                }
62
63                while current.get_next().is_some() {
64                    if let Some(next) = current.get_next_mut() {
65                        if *next.get_value() == value {
66                            let next_next = next.get_next_mut().take();
67                            current.set_next(next_next);
68                            self.len -= 1;
69                            return Ok(true);
70                        }
71                    }
72                    current = current.get_next_mut().as_mut().unwrap();
73                }
74            }
75        }
76
77        Err(Error::ValueNotFound)
78    }
79    /// Search for a value in the list, returns true if the value is found.
80    /// If the value is not found, it returns an error.
81    pub fn search(&self, value: T) -> Result<bool> {
82        match self.head.as_ref() {
83            None => return Err(Error::EmptyList),
84            Some(current) => {
85                let mut current = current;
86                if current.get_next().is_none() {
87                    return Ok(*current.get_value() == value);
88                }
89                while current.get_next().is_some() {
90                    if *current.get_value() == value {
91                        return Ok(true);
92                    }
93                    current = current.get_next().as_ref().unwrap();
94                }
95            }
96        }
97        Err(Error::ValueNotFound)
98    }
99    /// Update a value in the list, returns true if the value is found and updated.
100    /// If the value is not found, it returns an error.
101    pub fn update(&mut self, old_value: T, new_value: T) -> Result<bool> {
102        match self.head.as_mut() {
103            None => return Err(Error::EmptyList),
104            Some(mut current) => {
105                while current.get_next().is_some() {
106                    if *current.get_value() == old_value {
107                        current.set_value(new_value);
108                        return Ok(true);
109                    }
110                    current = current.get_next_mut().as_mut().unwrap();
111                }
112            }
113        }
114        Err(Error::ValueNotFound)
115    }
116    /// Create a new instance of the double linked list from a vector.
117    pub fn from_vec(values: Vec<T>) -> Self {
118        let mut list = Self::new();
119        for value in values {
120            list.append(value);
121        }
122        list
123    }
124    /// Remove the last node from the list.
125    /// Returns the value of the removed node.
126    /// If the list is empty, it returns an error.
127    pub fn pop(&mut self) -> Result<Option<T>> {
128        if self.is_empty() {
129            return Err(Error::EmptyList);
130        }
131
132        match self.head.as_mut() {
133            None => return Err(Error::EmptyList),
134            Some(mut current) => {
135                if current.get_next().is_none() {
136                    let last_node = current.get_value().clone();
137                    self.head = None;
138                    self.len -= 1;
139                    return Ok(Some(last_node));
140                }
141
142                while current.get_next().is_some() {
143                    if let Some(next) = current.get_next_mut() {
144                        if next.get_next().is_none() {
145                            let last_node = next.get_value().clone();
146                            current.set_next(None);
147                            self.len -= 1;
148                            return Ok(Some(last_node));
149                        }
150                    }
151                    current = current.get_next_mut().as_mut().unwrap();
152                }
153            }
154        }
155        Ok(None)
156    }
157
158    pub fn print(&self) {
159        let mut current = &self.head;
160        while let Some(node) = current {
161            print!("{:?} -> ", node.get_value());
162            current = node.get_next();
163        }
164        println!("None");
165    }
166    /// Check if the list is empty.
167    pub fn is_empty(&self) -> bool {
168        self.head.is_none()
169    }
170    /// Get an element from the list by index.
171    /// Returns an error if the list is empty or the index is out of bounds.
172    /// If the index is valid, it returns the value of the node.
173    pub fn get(&self, index: usize) -> Result<Option<&T>> {
174        if self.is_empty() {
175            return Err(Error::EmptyList);
176        }
177
178        let mut current = &self.head;
179        let mut current_index = 0;
180
181        while current_index <= index {
182            if current_index == index {
183                return Ok(Some(current.as_ref().unwrap().get_value()));
184            }
185            current = current.as_ref().unwrap().get_next();
186            current_index += 1;
187        }
188
189        Err(Error::IndexOutOfBounds)
190    }
191}
192
193// region:    --- Tests
194
195#[cfg(test)]
196mod test {
197    use super::*;
198
199    #[test]
200    fn test_singly_list_ops() {
201        let mut list = Singly::new();
202        assert!(list.remove(99).is_err());
203        list.append(1);
204        list.append(2);
205        list.append(3);
206        list.append(4);
207        list.append(5);
208        assert_eq!(list.is_empty(), false);
209        assert_eq!(list.search(3).unwrap(), true);
210        assert_eq!(list.update(3, 6).unwrap(), true);
211        let list2 = Singly::from_vec(vec!["hello", "world", "rust"]);
212        assert_eq!(list.pop().unwrap().unwrap(), 5);
213        assert_eq!(list.pop().unwrap().unwrap(), 4);
214        assert_eq!(list.pop().unwrap().unwrap(), 6);
215        assert_eq!(list.pop().unwrap().unwrap(), 2);
216        assert_eq!(list.pop().unwrap().unwrap(), 1);
217        assert_eq!(list2.get(2).unwrap(), Some(&"rust"));
218        list2.print();
219    }
220
221    #[test]
222    fn test_singly_list_errors() {
223        let mut list = Singly::new();
224        assert!(list.is_empty());
225        assert!(list.remove(99).is_err());
226        assert!(list.update(99, 100).is_err());
227        assert!(list.pop().is_err());
228        assert!(list.get(0).is_err());
229        assert!(list.search(6).is_err());
230    }
231}
232
233// endregion: --- Tests