Skip to main content

plain_ds/list/
singly_linked.rs

1//! This module contains singly-linked list implementation.
2
3use std::ptr;
4
5use super::api::List;
6use super::common::ListCommon;
7use super::node_one_link::{Node, merge_sort};
8use crate::core::{DSError, Result};
9
10/// A singly-linked list implementation with efficient insertion at the front and back.
11///
12/// The `SinglyLinkedList` stores elements in a linear sequence where each element
13/// points to the next one. It provides O(1) push and pop_front operations.
14///
15/// # Type Parameters
16/// * `T`: The type of elements stored in the list.
17///
18///
19/// # Examples
20/// ```
21/// use plain_ds::SinglyLinkedList;
22///
23/// let mut list = SinglyLinkedList::new();
24/// list.push(1);
25/// list.push(2);
26/// list.push(3);
27///
28/// assert_eq!(list.pop(), Some(3));
29/// assert_eq!(list.len(), 2);
30/// ```
31pub struct SinglyLinkedList<T> {
32    state: ListCommon<T>,
33}
34
35impl<T> SinglyLinkedList<T> {
36    /// Creates empty singly-linked list.
37    pub fn new() -> Self {
38        Self {
39            state: ListCommon::new(),
40        }
41    }
42
43    /// Creates list from slice.
44    ///
45    /// **Efficiency**: O(n)
46    pub fn from_slice(slice: &[T]) -> Self
47    where
48        T: Clone,
49    {
50        let mut list = SinglyLinkedList::new();
51        for value in slice {
52            list.push((*value).clone());
53        }
54        list
55    }
56
57    /// Collect list values into a vector.
58    ///
59    /// **Efficiency**: O(n)
60    pub fn to_vec(&self) -> Vec<T>
61    where
62        T: Clone,
63    {
64        self.state.to_vec()
65    }
66
67    /// Adds a new node to the front of the list.
68    ///
69    /// **Efficiency**: O(1)
70    pub fn push_front(&mut self, payload: T) {
71        let ptr = Box::into_raw(Box::new(Node::new(payload)));
72        if self.is_empty() {
73            self.state.last = ptr;
74        } else {
75            unsafe { (*ptr).next = self.state.head }
76        }
77        self.state.head = ptr;
78        self.state.size += 1;
79    }
80
81    /// Insert a new node at the specified location in the list.
82    /// Error returns, if the index out of bounds.
83    ///
84    /// **Efficiency**: O(n)
85    pub fn insert(&mut self, index: usize, payload: T) -> Result<()> {
86        if index > self.state.size {
87            return Err(DSError::IndexOutOfBounds {
88                index,
89                len: self.state.size,
90            });
91        }
92        if index == self.state.size {
93            self.push(payload);
94            return Ok(());
95        }
96        if index == 0 {
97            self.push_front(payload);
98            return Ok(());
99        }
100
101        // Finding the insert point
102        let mut current = self.state.head;
103        let mut index = index;
104        unsafe {
105            while index > 1 {
106                current = (*current).next;
107                index -= 1;
108            }
109        }
110
111        let mut boxed = Box::new(Node::new(payload));
112        unsafe {
113            boxed.next = (*current).next;
114            (*current).next = Box::into_raw(boxed);
115        }
116
117        self.state.size += 1;
118        Ok(())
119    }
120
121    /// Finds the first node whose payload satisfies the predicate and returns its index.
122    /// Returns `None` if there is no such node.
123    ///
124    /// **Efficiency**: O(n)
125    pub fn find_if(&self, predicate: impl Fn(&T) -> bool) -> Option<usize>
126    where
127        T: PartialEq,
128    {
129        self.state.find_if(predicate)
130    }
131
132    /// Sorts the list in ascending order using merge sort algorithm.
133    ///
134    /// **Efficiency**: O(n log n)
135    ///
136    /// Space complexity: O(log n) due to recursion stack
137    pub fn sort(&mut self)
138    where
139        T: PartialOrd + Default,
140    {
141        if self.state.len() <= 1 {
142            return; // Already sorted
143        }
144
145        // Extract the head and reset the list
146        let head = self.state.head;
147        self.state.head = ptr::null_mut();
148        self.state.last = ptr::null_mut();
149        self.state.size = 0;
150
151        // Sort the extracted nodes and get new head
152        let sorted_head = merge_sort(head);
153
154        // Reconstruct the list with sorted nodes
155        self.rebuild_from_sorted_list(sorted_head);
156    }
157
158    /// Rebuilds the list from a sorted list of nodes
159    fn rebuild_from_sorted_list(&mut self, head: *mut Node<T>) {
160        self.state.head = head;
161        self.state.size = 0;
162
163        if head.is_null() {
164            self.state.last = std::ptr::null_mut();
165            return;
166        }
167
168        // Traverse to find the last node and count size
169        let mut current = head;
170        self.state.size = 1;
171
172        unsafe {
173            while !(*current).next.is_null() {
174                current = (*current).next;
175                self.state.size += 1;
176            }
177            self.state.last = current;
178        }
179    }
180}
181
182impl<'a, T: 'a> List<'a, T> for SinglyLinkedList<T> {
183    /// Returns list size.
184    ///
185    /// **Efficiency**: O(1)
186    fn len(&self) -> usize {
187        self.state.len()
188    }
189
190    /// Returns the payload value of the first node in the list.
191    ///
192    /// **Efficiency**: O(1)
193    fn head(&self) -> Option<&T> {
194        self.state.head()
195    }
196
197    /// Returns the payload value of the last node in the list.
198    ///
199    /// **Efficiency**: O(1)
200    fn last(&self) -> Option<&T> {
201        self.state.last()
202    }
203
204    /// Returns an iterator over the immutable items of the list.
205    fn iter(&self) -> impl Iterator<Item = &'a T> {
206        self.state.iter()
207    }
208
209    /// Returns an iterator over the mutable items of the list.
210    fn iter_mut(&mut self) -> impl Iterator<Item = &'a mut T> {
211        self.state.iter_mut()
212    }
213
214    /// Returns an iterator that consumes the list.
215    fn into_iter(self) -> impl Iterator<Item = T> {
216        self.state.into_iter()
217    }
218
219    /// Adds a new node to the end of the list.
220    ///
221    /// **Efficiency**: O(1)
222    fn push(&mut self, payload: T) {
223        self.state.push_back(payload);
224    }
225
226    /// Removes a node from the end of the list and returns its payload value.
227    ///
228    /// **Efficiency**: O(n)
229    fn pop_back(&mut self) -> Option<T> {
230        self.state.pop_back()
231    }
232
233    /// Removes a node from the front of the list and returns its payload value.
234    ///
235    /// **Efficiency**: O(1)
236    fn pop_front(&mut self) -> Option<T> {
237        self.state.pop_front()
238    }
239
240    /// Removes a node from the specified location in the list.
241    /// Error returns, if the index out of bounds.
242    ///
243    /// **Efficiency**: O(n)
244    fn remove(&mut self, index: usize) -> Result<T> {
245        self.state.remove(index)
246    }
247}
248
249#[cfg(test)]
250mod tests {
251    use super::*;
252
253    // Helper function to create a list with values [0, 1, 2, ..., n-1]
254    fn setup_list(n: usize) -> SinglyLinkedList<usize> {
255        let mut list = SinglyLinkedList::new();
256        for i in 0..n {
257            list.push(i);
258        }
259        list
260    }
261
262    #[test]
263    fn test_from_slice() {
264        let list = SinglyLinkedList::from_slice(&[2, 1, 5, 4, 3]);
265        assert_eq!(
266            list.to_vec(),
267            [2, 1, 5, 4, 3],
268            "The order of elements must be preserved"
269        );
270    }
271
272    mod get {
273        use super::*;
274
275        #[test]
276        fn test_get_empty_list() {
277            let list: SinglyLinkedList<i32> = SinglyLinkedList::new();
278            assert!(
279                list.get(0).is_err(),
280                "get() on empty list should return error"
281            );
282            assert!(
283                list.get(1).is_err(),
284                "get() with any index on empty list should return error"
285            );
286        }
287
288        #[test]
289        fn test_get_index_out_of_bounds() {
290            let mut list = SinglyLinkedList::new();
291            list.push(10);
292            list.push(20);
293            list.push(30);
294
295            assert!(
296                list.get(3).is_err(),
297                "get() with index == size should return error (out of bounds)"
298            );
299            assert!(
300                list.get(4).is_err(),
301                "get() with index > size should return error"
302            );
303            assert!(
304                list.get(100).is_err(),
305                "get() with large out-of-bounds index should return error"
306            );
307        }
308
309        #[test]
310        fn test_get_first_element() {
311            let mut list = SinglyLinkedList::new();
312            list.push(100);
313            list.push(200);
314            list.push(300);
315
316            let result = list.get(0).unwrap();
317            assert_eq!(*result, 100, "get(0) should return first element (100)");
318        }
319
320        #[test]
321        fn test_get_last_element() {
322            let mut list = SinglyLinkedList::new();
323            list.push(100);
324            list.push(200);
325            list.push(300);
326
327            let result = list.get(2).unwrap(); // index = size - 1
328            assert_eq!(
329                *result, 300,
330                "get(last_index) should return last element (300)"
331            );
332        }
333
334        #[test]
335        fn test_get_middle_element() {
336            let mut list = SinglyLinkedList::new();
337            list.push(10);
338            list.push(20);
339            list.push(30);
340            list.push(40);
341            list.push(50);
342
343            let result = list.get(2).unwrap(); // middle element
344            assert_eq!(*result, 30, "get(2) should return middle element (30)");
345
346            let result2 = list.get(1).unwrap();
347            assert_eq!(*result2, 20, "get(1) should return second element (20)");
348        }
349
350        #[test]
351        fn test_get_single_element_list() {
352            let mut list = SinglyLinkedList::new();
353            list.push(42);
354
355            let result = list.get(0).unwrap();
356            assert_eq!(
357                *result, 42,
358                "get(0) on single-element list should return that element"
359            );
360
361            assert!(
362                list.get(1).is_err(),
363                "get(1) on single-element list should be out of bounds"
364            );
365        }
366
367        #[test]
368        fn test_get_with_complex_types() {
369            // Test with String
370            let mut string_list = SinglyLinkedList::new();
371            string_list.push("apple".to_string());
372            string_list.push("banana".to_string());
373            string_list.push("cherry".to_string());
374
375            let first = string_list.get(0).unwrap();
376            assert_eq!(first, "apple", "get(0) should return 'apple'");
377
378            let last = string_list.get(2).unwrap();
379            assert_eq!(last, "cherry", "get(2) should return 'cherry'");
380
381            // Test with Vec
382            let mut vec_list = SinglyLinkedList::new();
383            vec_list.push(vec![1, 2]);
384            vec_list.push(vec![3, 4]);
385
386            let vec_result = vec_list.get(1).unwrap();
387            assert_eq!(vec_result, &vec![3, 4], "get(1) should return vec![3, 4]");
388        }
389
390        #[test]
391        fn test_get_preserves_list_integrity() {
392            let mut list = SinglyLinkedList::new();
393            list.push(1);
394            list.push(2);
395            list.push(3);
396
397            // Get element in the middle
398            let _ = list.get(1).unwrap();
399
400            // Verify list is unchanged
401            assert_eq!(
402                list.len(),
403                3,
404                "list length should remain unchanged after get()"
405            );
406            assert_eq!(list.head(), Some(&1), "head should remain the same");
407            assert_eq!(list.last(), Some(&3), "last should remain the same");
408
409            // Verify we can still get other elements
410            assert_eq!(
411                *list.get(0).unwrap(),
412                1,
413                "get(0) after get(1) should still work"
414            );
415            assert_eq!(
416                *list.get(2).unwrap(),
417                3,
418                "get(2) after get(1) should still work"
419            );
420        }
421
422        #[test]
423        fn test_get_mut_empty_list() {
424            let mut list: SinglyLinkedList<i32> = SinglyLinkedList::new();
425            assert!(
426                list.get_mut(0).is_err(),
427                "get_mut() on empty list should return error"
428            );
429        }
430
431        #[test]
432        fn test_get_mut_index_out_of_bounds() {
433            let mut list = SinglyLinkedList::new();
434            list.push(10);
435            list.push(20);
436
437            assert!(
438                list.get_mut(2).is_err(),
439                "get_mut() with index == size should return error"
440            );
441            assert!(
442                list.get_mut(5).is_err(),
443                "get_mut() with large out-of-bounds index should return error"
444            );
445        }
446
447        #[test]
448        fn test_get_mut_first_element() {
449            let mut list = SinglyLinkedList::new();
450            list.push(100);
451            list.push(200);
452            list.push(300);
453
454            let mut_ref = list.get_mut(0).unwrap();
455            *mut_ref = 999;
456
457            assert_eq!(
458                *list.get(0).unwrap(),
459                999,
460                "first element should be modified to 999"
461            );
462            assert_eq!(
463                *list.head().unwrap(),
464                999,
465                "head should reflect the modification"
466            );
467        }
468
469        #[test]
470        fn test_get_mut_last_element() {
471            let mut list = SinglyLinkedList::new();
472            list.push(100);
473            list.push(200);
474            list.push(300);
475
476            let mut_ref = list.get_mut(2).unwrap(); // last element
477            *mut_ref = 888;
478
479            assert_eq!(
480                *list.get(2).unwrap(),
481                888,
482                "last element should be modified to 888"
483            );
484            assert_eq!(
485                *list.last().unwrap(),
486                888,
487                "last should reflect the modification"
488            );
489        }
490
491        #[test]
492        fn test_get_mut_middle_element() {
493            let mut list = SinglyLinkedList::new();
494            list.push(10);
495            list.push(20);
496            list.push(30);
497            list.push(40);
498
499            let mut_ref = list.get_mut(2).unwrap(); // third element
500            *mut_ref *= 2; // 30 * 2 = 60
501
502            assert_eq!(
503                *list.get(2).unwrap(),
504                60,
505                "middle element should be doubled to 60"
506            );
507        }
508
509        #[test]
510        fn test_get_mut_single_element_list() {
511            let mut list = SinglyLinkedList::new();
512            list.push(42);
513
514            let mut_ref = list.get_mut(0).unwrap();
515            *mut_ref += 1;
516
517            assert_eq!(
518                *list.get(0).unwrap(),
519                43,
520                "single element should be modified to 43"
521            );
522        }
523
524        #[test]
525        fn test_get_mut_with_complex_types() {
526            // Test with String — modify by pushing more text
527            let mut string_list = SinglyLinkedList::new();
528            string_list.push("hello".to_string());
529            string_list.push("world".to_string());
530
531            let mut_str = string_list.get_mut(0).unwrap();
532            mut_str.push_str(" there");
533
534            assert_eq!(
535                string_list.get(0).unwrap(),
536                "hello there",
537                "first string should be modified"
538            );
539
540            // Test with Vec — modify by adding elements
541            let mut vec_list = SinglyLinkedList::new();
542            vec_list.push(vec![1, 2]);
543            vec_list.push(vec![3, 4]);
544
545            let mut_vec = vec_list.get_mut(1).unwrap();
546            mut_vec.push(5);
547
548            assert_eq!(
549                vec_list.get(1).unwrap(),
550                &vec![3, 4, 5],
551                "second vector should have new element"
552            );
553        }
554
555        #[test]
556        fn test_get_mut_preserves_list_integrity() {
557            let mut list = SinglyLinkedList::new();
558            list.push(1);
559            list.push(2);
560            list.push(3);
561
562            // Modify middle element
563            let mut_ref = list.get_mut(1).unwrap();
564            *mut_ref *= 10; // 2 becomes 20
565
566            // Verify list structure is intact
567            assert_eq!(
568                list.len(),
569                3,
570                "list length should remain unchanged after get_mut()"
571            );
572            assert_eq!(list.head(), Some(&1), "head should remain the same");
573            assert_eq!(list.last(), Some(&3), "last should remain the same");
574
575            // Verify other elements are accessible and unchanged
576            assert_eq!(
577                *list.get(0).unwrap(),
578                1,
579                "first element should be unchanged"
580            );
581            assert_eq!(*list.get(2).unwrap(), 3, "last element should be unchanged");
582        }
583
584        #[test]
585        fn test_multiple_get_mut_calls() {
586            let mut list = SinglyLinkedList::new();
587            list.push(10);
588            list.push(20);
589            list.push(30);
590
591            // First modification
592            let first = list.get_mut(0).unwrap();
593            *first += 5; // 10 becomes 15
594
595            // Second modification on different element
596            let last = list.get_mut(2).unwrap();
597            *last *= 2; // 30 becomes 60
598
599            // Final verification
600            let values: Vec<i32> = list.iter().copied().collect();
601            assert_eq!(
602                values,
603                vec![15, 20, 60],
604                "all modifications should be applied correctly"
605            );
606        }
607
608        #[test]
609        fn test_get_mut_then_get() {
610            let mut list = SinglyLinkedList::new();
611            list.push(5);
612            list.push(15);
613            list.push(25);
614
615            // Modify using get_mut
616            let mid = list.get_mut(1).unwrap();
617            *mid = 99;
618
619            // Immediately read using get
620            let mid_value = list.get(1).unwrap();
621
622            assert_eq!(
623                *mid_value, 99,
624                "get() should reflect changes made by get_mut()"
625            );
626        }
627
628        #[test]
629        fn test_get_mut_error_propagation() {
630            let mut list = SinglyLinkedList::new();
631            list.push(1);
632            list.push(2);
633
634            // Try to get mutable reference to out-of-bounds index
635            let result = list.get_mut(5);
636            assert!(
637                result.is_err(),
638                "get_mut() with out-of-bounds index should return error"
639            );
640
641            // Ensure list is still valid after failed operation
642            assert_eq!(
643                list.len(),
644                2,
645                "list should remain unchanged after failed get_mut()"
646            );
647            assert_eq!(*list.get(0).unwrap(), 1, "first element should remain 1");
648            assert_eq!(*list.get(1).unwrap(), 2, "second element should remain 2");
649        }
650    }
651
652    mod push {
653        use super::*;
654
655        #[test]
656        fn test_push_to_empty_list_updates_head_and_last() {
657            let mut list = SinglyLinkedList::new();
658
659            list.push(100);
660            assert_eq!(list.len(), 1);
661            assert_eq!(list.head(), Some(&100));
662            assert_eq!(list.last(), Some(&100));
663
664            let mut list2 = SinglyLinkedList::new();
665            list2.push_front(200);
666            assert_eq!(list2.len(), 1);
667            assert_eq!(list2.head(), Some(&200));
668            assert_eq!(list2.last(), Some(&200));
669        }
670
671        #[test]
672        fn test_push_front() {
673            let mut list: SinglyLinkedList<u8> = SinglyLinkedList::new();
674            assert_eq!(list.len(), 0, "is_empty() returns `false` after creation");
675
676            list.push_front(1);
677            assert_eq!(list.len(), 1, "bad length after push_front()");
678            assert_eq!(list.head(), Some(&1), "incorrect head after push_front()");
679            assert_eq!(list.last(), Some(&1), "incorrect last after push_front()");
680            assert_ne!(
681                list.len(),
682                0,
683                "is_empty() returns `true` after push_front()"
684            );
685
686            list.push_front(2);
687            assert_eq!(list.len(), 2, "bad length after push_front()");
688            assert!(list.head().is_some(), "head is None after push_front()");
689            assert_eq!(list.head(), Some(&2), "incorrect head payload");
690            assert_eq!(list.last(), Some(&1), "incorrect last after push_front()");
691            assert_ne!(
692                list.len(),
693                0,
694                "is_empty() returns `true` after push_front()"
695            );
696
697            let mut list: SinglyLinkedList<String> = SinglyLinkedList::new();
698            list.push_front("hello".to_string());
699            assert_eq!(list.len(), 1, "bad length after push_front()");
700            assert!(list.head().is_some(), "head is None after push_front()");
701            assert_eq!(list.head().unwrap(), "hello", "incorrect head payload");
702
703            let mut list: SinglyLinkedList<&[char]> = SinglyLinkedList::new();
704            list.push_front(&['a', 'b', 'c']);
705            assert_eq!(list.len(), 1, "bad length after push_front()");
706            assert!(list.head().is_some(), "head is None after push_front()");
707            assert_eq!(
708                list.head().unwrap(),
709                &['a', 'b', 'c'],
710                "incorrect head payload"
711            );
712        }
713
714        #[test]
715        fn test_mix_push() {
716            let mut list: SinglyLinkedList<u8> = SinglyLinkedList::new();
717            assert_eq!(list.len(), 0, "is_empty() returns `false` after creation");
718
719            list.push(1);
720            assert_eq!(list.len(), 1, "bad length after push_back()");
721            assert_eq!(list.head(), Some(&1), "incorrect head after push_back()");
722            assert_eq!(list.last(), Some(&1), "incorrect last after push_back()");
723            assert_ne!(list.len(), 0, "is_empty() returns `true` after push_back()");
724
725            list.push_front(2);
726            assert_eq!(list.len(), 2, "bad length after push_front()");
727            assert!(list.head().is_some(), "head is None after push_front()");
728            assert_eq!(list.head(), Some(&2), "incorrect head payload");
729            assert_eq!(list.last(), Some(&1), "incorrect last after push_front()");
730            assert_ne!(
731                list.len(),
732                0,
733                "is_empty() returns `true` after push_front()"
734            );
735
736            list.push(3);
737            assert_eq!(list.len(), 3, "bad length after push_back()");
738            assert!(list.head().is_some(), "head is None after push_back()");
739            assert_eq!(list.head(), Some(&2), "incorrect head payload");
740            assert_eq!(list.last(), Some(&3), "incorrect last after push_back()");
741            assert_ne!(list.len(), 0, "is_empty() returns `true` after push_back()");
742        }
743    }
744
745    mod mixed {
746        use super::*;
747
748        #[test]
749        fn test_mixed_push_pop_operations() {
750            let mut list = SinglyLinkedList::new();
751
752            list.push(1);
753            list.push_front(0);
754            list.push(2);
755
756            // List: [0, 1, 2]
757            assert_eq!(list.len(), 3);
758            assert_eq!(list.head(), Some(&0));
759            assert_eq!(list.last(), Some(&2));
760
761            assert_eq!(list.pop_front(), Some(0));
762            assert_eq!(list.pop_back(), Some(2));
763            assert_eq!(list.pop_front(), Some(1));
764            assert!(list.is_empty());
765
766            // Try one more pop
767            assert_eq!(list.pop_back(), None);
768            assert_eq!(list.pop_front(), None);
769        }
770
771        #[test]
772        fn test_size_consistency_after_operations() {
773            let mut list = SinglyLinkedList::new();
774
775            // Push back
776            list.push(10);
777            assert_eq!(list.len(), 1, "size after push(10) should be 1");
778
779            list.push(20);
780            assert_eq!(list.len(), 2, "size after second push should be 2");
781
782            // Pop back
783            list.pop_back();
784            assert_eq!(list.len(), 1, "size after pop_back should be 1");
785
786            // Push front
787            list.push_front(5);
788            assert_eq!(list.len(), 2, "size after push_front(5) should be 2");
789
790            // Pop front
791            list.pop_front();
792            assert_eq!(list.len(), 1, "size after pop_front should be 1");
793
794            // Final pop
795            list.pop_back();
796            assert_eq!(list.len(), 0, "size should be 0 after all pops");
797            assert!(list.is_empty(), "list should be empty");
798        }
799
800        #[test]
801        fn test_head_last_consistency_after_mixed_operations() {
802            let mut list = SinglyLinkedList::new();
803
804            // Start: empty
805            assert_eq!(list.head(), None);
806            assert_eq!(list.last(), None);
807
808            // push(1)
809            list.push(1);
810            assert_eq!(list.head(), Some(&1));
811            assert_eq!(list.last(), Some(&1));
812
813            // push_front(0)
814            list.push_front(0);
815            assert_eq!(list.head(), Some(&0));
816            assert_eq!(list.last(), Some(&1));
817
818            // push(2)
819            list.push(2);
820            assert_eq!(list.head(), Some(&0));
821            assert_eq!(list.last(), Some(&2));
822
823            // pop_front() → removes 0
824            list.pop_front();
825            assert_eq!(list.head(), Some(&1));
826            assert_eq!(list.last(), Some(&2));
827
828            // pop_back() → removes 2
829            list.pop_back();
830            assert_eq!(list.head(), Some(&1));
831            assert_eq!(list.last(), Some(&1));
832
833            // Final pop
834            list.pop_front();
835            assert_eq!(list.head(), None);
836            assert_eq!(list.last(), None);
837            assert!(list.is_empty());
838        }
839    }
840
841    mod complex_types {
842        use super::*;
843
844        #[test]
845        fn test_complex_types_string() {
846            let mut list = SinglyLinkedList::new();
847            list.push("hello".to_string());
848            list.push("world".to_string());
849
850            assert_eq!(list.len(), 2);
851            assert_eq!(list.head().unwrap(), "hello");
852            assert_eq!(list.last().unwrap(), "world");
853
854            assert_eq!(list.pop_front().unwrap(), "hello".to_string());
855            assert_eq!(list.pop_back().unwrap(), "world".to_string());
856            assert!(list.is_empty());
857        }
858
859        #[test]
860        fn test_complex_types_vec() {
861            let mut list = SinglyLinkedList::new();
862            list.push(vec![1, 2]);
863            list.push(vec![3, 4]);
864
865            assert_eq!(list.len(), 2);
866            assert_eq!(list.head().unwrap(), &vec![1, 2]);
867            assert_eq!(list.last().unwrap(), &vec![3, 4]);
868
869            let popped_front = list.pop_front().unwrap();
870            assert_eq!(popped_front, vec![1, 2]);
871
872            let popped_back = list.pop_back().unwrap();
873            assert_eq!(popped_back, vec![3, 4]);
874            assert!(list.is_empty());
875        }
876    }
877
878    mod insert {
879        use super::*;
880
881        #[test]
882        fn test_insert_at_beginning_empty_list() {
883            let mut list = SinglyLinkedList::new();
884            assert!(
885                list.insert(0, 42).is_ok(),
886                "insert at index 0 in empty list should succeed"
887            );
888            assert_eq!(list.len(), 1, "list size should be 1 after insertion");
889            assert_eq!(list.head(), Some(&42), "head should contain inserted value");
890            assert_eq!(list.last(), Some(&42), "last should contain inserted value");
891        }
892
893        #[test]
894        fn test_insert_at_beginning_non_empty_list() {
895            let mut list = setup_list(3); // [0, 1, 2]
896            assert!(
897                list.insert(0, 99).is_ok(),
898                "insert at beginning should succeed"
899            );
900            assert_eq!(list.len(), 4, "size should increase by 1");
901            assert_eq!(list.head(), Some(&99), "new head should be 99");
902            assert_eq!(list.find(&99), Some(0), "find should locate 99 at index 0");
903        }
904
905        #[test]
906        fn test_insert_at_end() {
907            let mut list = setup_list(2); // [0, 1]
908            assert!(
909                list.insert(2, 999).is_ok(),
910                "insert at end (index == size) should succeed"
911            );
912            assert_eq!(list.len(), 3, "size should increase by 1");
913            assert_eq!(list.last(), Some(&999), "last element should be 999");
914            assert_eq!(
915                list.find(&999),
916                Some(2),
917                "find should locate 999 at index 2"
918            );
919        }
920
921        #[test]
922        fn test_insert_in_middle() {
923            let mut list = setup_list(3); // [0, 1, 2]
924            assert!(
925                list.insert(1, 50).is_ok(),
926                "insert in middle should succeed"
927            );
928            assert_eq!(list.len(), 4, "size should increase by 1");
929
930            // Verify the order: [0, 50, 1, 2]
931            let mut iter = list.iter();
932            assert_eq!(iter.next(), Some(&0));
933            assert_eq!(iter.next(), Some(&50));
934            assert_eq!(iter.next(), Some(&1));
935            assert_eq!(iter.next(), Some(&2));
936        }
937
938        #[test]
939        fn test_insert_out_of_bounds() {
940            let mut list = setup_list(2); // [0, 1]
941
942            // Index greater than size
943            assert!(
944                list.insert(3, 42).is_err(),
945                "insert with index > size should return error"
946            );
947
948            // Very large index
949            assert!(
950                list.insert(100, 42).is_err(),
951                "insert with large out-of-bounds index should return error"
952            );
953
954            // Empty list with non-zero index
955            let mut empty_list = SinglyLinkedList::new();
956            assert!(
957                empty_list.insert(1, 42).is_err(),
958                "insert to empty list with index > 0 should return error"
959            );
960        }
961
962        #[test]
963        fn test_insert_with_complex_types_string() {
964            let mut list = SinglyLinkedList::new();
965            list.push("first".to_string());
966            list.push("third".to_string());
967
968            assert!(
969                list.insert(1, "second".to_string()).is_ok(),
970                "insert string in middle should succeed"
971            );
972            assert_eq!(list.len(), 3, "size should be 3 after insertion");
973
974            // Verify order: ["first", "second", "third"]
975            let values: Vec<String> = list.iter().map(|payload| payload.clone()).collect();
976            assert_eq!(values, vec!["first", "second", "third"]);
977        }
978
979        #[test]
980        fn test_insert_multiple_times() {
981            let mut list = SinglyLinkedList::new();
982
983            // Insert at various positions multiple times
984            assert!(list.insert(0, 10).is_ok());
985            assert!(list.insert(1, 30).is_ok());
986            assert!(list.insert(1, 20).is_ok()); // Insert between 10 and 30
987
988            assert_eq!(list.len(), 3, "final size should be 3");
989
990            // Expected order: [10, 20, 30]
991            let mut iter = list.iter();
992            assert_eq!(iter.next(), Some(&10));
993            assert_eq!(iter.next(), Some(&20));
994            assert_eq!(iter.next(), Some(&30));
995        }
996
997        #[test]
998        fn test_insert_preserves_head_and_last_pointers() {
999            let mut list = setup_list(2); // [0, 1]
1000
1001            // Insert in the middle
1002            assert!(list.insert(1, 5).is_ok());
1003
1004            // Head should still be the first element
1005            assert_eq!(list.head(), Some(&0), "head pointer should remain correct");
1006
1007            // Last should still be the last element
1008            assert_eq!(list.last(), Some(&1), "last pointer should remain correct");
1009        }
1010
1011        #[test]
1012        fn test_insert_edge_cases() {
1013            // Test inserting into a list with one element
1014            let mut single_element = SinglyLinkedList::new();
1015            single_element.push(100);
1016
1017            // Insert at beginning (should work)
1018            assert!(single_element.insert(0, 50).is_ok());
1019            assert_eq!(single_element.find(&50), Some(0));
1020            assert_eq!(single_element.find(&100), Some(1));
1021
1022            // Insert at end (should work)
1023            assert!(single_element.insert(2, 150).is_ok());
1024            assert_eq!(single_element.find(&150), Some(2));
1025        }
1026    }
1027
1028    mod clear {
1029        use super::*;
1030
1031        #[test]
1032        fn test_clear_empty_list() {
1033            let mut list = SinglyLinkedList::<u8>::new();
1034            assert!(list.is_empty(), "list should be empty initially");
1035
1036            list.clear();
1037
1038            assert!(
1039                list.is_empty(),
1040                "clear() on empty list should leave it empty"
1041            );
1042            assert_eq!(
1043                list.len(),
1044                0,
1045                "length should remain 0 after clear() on empty list"
1046            );
1047            assert_eq!(
1048                list.head(),
1049                None,
1050                "head should be None after clear() on empty list"
1051            );
1052            assert_eq!(
1053                list.last(),
1054                None,
1055                "last should be None after clear() on empty list"
1056            );
1057        }
1058
1059        #[test]
1060        fn test_clear_single_element_list() {
1061            let mut list = SinglyLinkedList::new();
1062            list.push(42);
1063            assert!(!list.is_empty(), "list should not be empty before clear()");
1064            assert_eq!(list.len(), 1, "list should have length 1 before clear()");
1065
1066            list.clear();
1067
1068            assert!(list.is_empty(), "list should be empty after clear()");
1069            assert_eq!(list.len(), 0, "length should be 0 after clear()");
1070            assert_eq!(list.head(), None, "head should be None after clear()");
1071            assert_eq!(list.last(), None, "last should be None after clear()");
1072        }
1073
1074        #[test]
1075        fn test_clear_multiple_elements_list() {
1076            let mut list = SinglyLinkedList::new();
1077            list.push(10);
1078            list.push(20);
1079            list.push(30);
1080            assert_eq!(list.len(), 3, "list should have 3 elements before clear()");
1081
1082            list.clear();
1083
1084            assert!(
1085                list.is_empty(),
1086                "list should be empty after clearing multiple elements"
1087            );
1088            assert_eq!(
1089                list.len(),
1090                0,
1091                "length should be 0 after clearing multiple elements"
1092            );
1093            assert_eq!(
1094                list.head(),
1095                None,
1096                "head should be None after clearing multiple elements"
1097            );
1098            assert_eq!(
1099                list.last(),
1100                None,
1101                "last should be None after clearing multiple elements"
1102            );
1103        }
1104
1105        #[test]
1106        fn test_clear_then_reuse_list() {
1107            let mut list = SinglyLinkedList::new();
1108            list.push(1);
1109            list.push(2);
1110
1111            list.clear();
1112            assert!(list.is_empty(), "list should be empty after clear()");
1113
1114            // Reuse the list after clearing
1115            list.push(100);
1116            list.push(200);
1117
1118            assert_eq!(
1119                list.len(),
1120                2,
1121                "list should accept new elements after clear()"
1122            );
1123            assert_eq!(*list.head().unwrap(), 100, "new head should be 100");
1124            assert_eq!(*list.last().unwrap(), 200, "new last should be 200");
1125        }
1126
1127        #[test]
1128        fn test_clear_with_complex_types() {
1129            // Test with String
1130            let mut string_list = SinglyLinkedList::new();
1131            string_list.push("apple".to_string());
1132            string_list.push("banana".to_string());
1133
1134            string_list.clear();
1135            assert!(
1136                string_list.is_empty(),
1137                "string list should be empty after clear()"
1138            );
1139            assert_eq!(
1140                string_list.len(),
1141                0,
1142                "string list length should be 0 after clear()"
1143            );
1144
1145            // Test with Vec
1146            let mut vec_list = SinglyLinkedList::new();
1147            vec_list.push(vec![1, 2]);
1148            vec_list.push(vec![3, 4]);
1149
1150            vec_list.clear();
1151            assert!(
1152                vec_list.is_empty(),
1153                "vec list should be empty after clear()"
1154            );
1155            assert_eq!(
1156                vec_list.len(),
1157                0,
1158                "vec list length should be 0 after clear()"
1159            );
1160        }
1161
1162        #[test]
1163        fn test_clear_preserves_list_integrity() {
1164            let mut list = SinglyLinkedList::new();
1165            list.push(5);
1166            list.push(10);
1167            list.push(15);
1168
1169            let initial_len = list.len();
1170            let head_before = list.head().cloned();
1171            let last_before = list.last().cloned();
1172            assert_eq!(initial_len, 3);
1173            assert_eq!(head_before.unwrap(), 5);
1174            assert_eq!(last_before.unwrap(), 15);
1175
1176            list.clear();
1177
1178            // Verify the list is properly cleared
1179            assert!(list.is_empty(), "list should be empty after clear()");
1180            assert_eq!(list.len(), 0, "length should be 0 after clear()");
1181            assert_eq!(list.head(), None, "head should be None after clear()");
1182            assert_eq!(list.last(), None, "last should be None after clear()");
1183
1184            // Ensure we can create a new list and it works correctly
1185            let mut new_list = SinglyLinkedList::new();
1186            new_list.push(100);
1187            assert_eq!(
1188                new_list.len(),
1189                1,
1190                "new list should work correctly after previous clear()"
1191            );
1192        }
1193
1194        #[test]
1195        fn test_clear_performance_consistency() {
1196            // Test that clear() works correctly regardless of list size
1197            for size in &[0, 1, 5, 10, 100] {
1198                let mut list = SinglyLinkedList::new();
1199
1200                // Fill list with values
1201                for i in 0..*size {
1202                    list.push(i);
1203                }
1204
1205                assert_eq!(
1206                    list.len(),
1207                    *size,
1208                    "list should have correct length before clear() for size {}",
1209                    size
1210                );
1211
1212                list.clear();
1213
1214                assert!(
1215                    list.is_empty(),
1216                    "list of size {} should be empty after clear()",
1217                    size
1218                );
1219                assert_eq!(
1220                    list.len(),
1221                    0,
1222                    "list of size {} should have length 0 after clear()",
1223                    size
1224                );
1225                assert_eq!(
1226                    list.head(),
1227                    None,
1228                    "head should be None for cleared list of size {}",
1229                    size
1230                );
1231                assert_eq!(
1232                    list.last(),
1233                    None,
1234                    "last should be None for cleared list of size {}",
1235                    size
1236                );
1237            }
1238        }
1239
1240        #[test]
1241        fn test_clear_after_mixed_operations() {
1242            let mut list = SinglyLinkedList::new();
1243
1244            // Perform various operations
1245            list.push(1);
1246            list.push_front(0);
1247            list.push(2);
1248            list.pop_front(); // removes 0
1249            list.push(3);
1250
1251            // List should now be [1, 2, 3]
1252            assert_eq!(
1253                list.len(),
1254                3,
1255                "list should have 3 elements after mixed operations"
1256            );
1257            assert_eq!(
1258                *list.head().unwrap(),
1259                1,
1260                "head should be 1 after mixed operations"
1261            );
1262            assert_eq!(
1263                *list.last().unwrap(),
1264                3,
1265                "last should be 3 after mixed operations"
1266            );
1267
1268            list.clear();
1269
1270            assert!(
1271                list.is_empty(),
1272                "list should be empty after clear() following mixed operations"
1273            );
1274            assert_eq!(
1275                list.len(),
1276                0,
1277                "length should be 0 after clear() following mixed operations"
1278            );
1279            assert_eq!(
1280                list.head(),
1281                None,
1282                "head should be None after clear() following mixed operations"
1283            );
1284            assert_eq!(
1285                list.last(),
1286                None,
1287                "last should be None after clear() following mixed operations"
1288            );
1289        }
1290    }
1291
1292    mod sort {
1293        use super::*;
1294
1295        #[test]
1296        fn test_sort_empty_list() {
1297            let mut list = SinglyLinkedList::<i32>::new();
1298            assert_eq!(list.len(), 0, "list should be empty initially");
1299
1300            list.sort();
1301
1302            assert_eq!(list.len(), 0, "empty list should remain empty after sort()");
1303            assert!(list.is_empty(), "empty list should be empty after sort()");
1304        }
1305
1306        #[test]
1307        fn test_sort_single_element() {
1308            let mut list = SinglyLinkedList::new();
1309            list.push(42);
1310            assert_eq!(list.len(), 1, "list should have one element");
1311
1312            list.sort();
1313
1314            assert_eq!(
1315                list.len(),
1316                1,
1317                "single element list should have same length after sort()"
1318            );
1319            let values = list.to_vec();
1320            assert_eq!(values, vec![42], "single element should remain unchanged");
1321        }
1322
1323        #[test]
1324        fn test_sort_already_sorted() {
1325            let mut list = SinglyLinkedList::from_slice(&[1, 2, 3, 4, 5]);
1326            assert_eq!(list.len(), 5, "list should have 5 elements");
1327
1328            list.sort();
1329
1330            let values = list.to_vec();
1331            assert_eq!(
1332                values,
1333                vec![1, 2, 3, 4, 5],
1334                "already sorted list should remain sorted"
1335            );
1336        }
1337
1338        #[test]
1339        fn test_sort_reverse_sorted() {
1340            let mut list = SinglyLinkedList::from_slice(&[5, 4, 3, 2, 1]);
1341            assert_eq!(list.len(), 5, "list should have 5 elements");
1342
1343            list.sort();
1344
1345            let values = list.to_vec();
1346            assert_eq!(
1347                values,
1348                vec![1, 2, 3, 4, 5],
1349                "reverse sorted list should become ascending"
1350            );
1351        }
1352
1353        #[test]
1354        fn test_sort_random_order() {
1355            let mut list = SinglyLinkedList::from_slice(&[3, 1, 4, 1, 5, 9, 2, 6]);
1356            assert_eq!(list.len(), 8, "list should have 8 elements");
1357
1358            list.sort();
1359
1360            let values = list.to_vec();
1361            assert_eq!(
1362                values,
1363                vec![1, 1, 2, 3, 4, 5, 6, 9],
1364                "random order list should be sorted correctly"
1365            );
1366        }
1367
1368        #[test]
1369        fn test_sort_with_duplicates() {
1370            let mut list = SinglyLinkedList::from_slice(&[2, 2, 1, 1, 3, 3]);
1371            assert_eq!(list.len(), 6, "list should have 6 elements");
1372
1373            list.sort();
1374
1375            let values = list.to_vec();
1376            assert_eq!(
1377                values,
1378                vec![1, 1, 2, 2, 3, 3],
1379                "list with duplicates should be sorted with duplicates preserved"
1380            );
1381        }
1382
1383        #[test]
1384        fn test_sort_two_elements_unsorted() {
1385            let mut list = SinglyLinkedList::from_slice(&[2, 1]);
1386            assert_eq!(list.len(), 2, "list should have 2 elements");
1387
1388            list.sort();
1389
1390            let values = list.to_vec();
1391            assert_eq!(
1392                values,
1393                vec![1, 2],
1394                "two elements should be sorted in ascending order"
1395            );
1396        }
1397
1398        #[test]
1399        fn test_sort_two_elements_sorted() {
1400            let mut list = SinglyLinkedList::from_slice(&[1, 2]);
1401            assert_eq!(list.len(), 2, "list should have 2 elements");
1402
1403            list.sort();
1404
1405            let values = list.to_vec();
1406            assert_eq!(
1407                values,
1408                vec![1, 2],
1409                "already sorted two elements should remain the same"
1410            );
1411        }
1412
1413        #[test]
1414        fn test_sort_large_list() {
1415            // Create a large list with random-like pattern
1416            let mut data: Vec<i32> = (1..=1000).collect();
1417            // Shuffle by reversing every 10 elements
1418            for chunk in data.chunks_mut(10) {
1419                chunk.reverse();
1420            }
1421
1422            let mut list = SinglyLinkedList::new();
1423            for &value in &data {
1424                list.push(value);
1425            }
1426
1427            assert_eq!(list.len(), 1000, "large list should have 1000 elements");
1428
1429            list.sort();
1430
1431            let sorted_data: Vec<i32> = (1..=1000).collect();
1432            let values = list.to_vec();
1433            assert_eq!(values, sorted_data, "large list should be sorted correctly");
1434        }
1435
1436        #[test]
1437        fn test_sort_after_operations() {
1438            let mut list = SinglyLinkedList::new();
1439
1440            // Perform various operations
1441            list.push(5);
1442            list.push_front(1);
1443            list.push(3);
1444            list.pop_front(); // removes 1
1445            list.push(2);
1446
1447            // List should now be [5, 3, 2]
1448            assert_eq!(
1449                list.len(),
1450                3,
1451                "list should have 3 elements after mixed operations"
1452            );
1453
1454            list.sort();
1455
1456            let values = list.to_vec();
1457            assert_eq!(
1458                values,
1459                vec![2, 3, 5],
1460                "list after mixed operations should be sorted correctly"
1461            );
1462        }
1463
1464        #[test]
1465        fn test_sort_string_list() {
1466            let mut list = SinglyLinkedList::new();
1467            list.push("zebra".to_string());
1468            list.push("apple".to_string());
1469            list.push("banana".to_string());
1470            list.push("cherry".to_string());
1471
1472            assert_eq!(list.len(), 4, "string list should have 4 elements");
1473
1474            list.sort();
1475
1476            let values: Vec<String> = list.into_iter().collect();
1477
1478            assert_eq!(
1479                values,
1480                vec![
1481                    "apple".to_string(),
1482                    "banana".to_string(),
1483                    "cherry".to_string(),
1484                    "zebra".to_string()
1485                ],
1486                "string list should be sorted alphabetically"
1487            );
1488        }
1489
1490        #[test]
1491        fn test_sort_preserves_last_pointer() {
1492            let mut list = SinglyLinkedList::from_slice(&[3, 1, 4, 2]);
1493
1494            list.sort();
1495
1496            // Verify that last pointer is correctly set to the last node
1497            let last_value = unsafe { (*list.state.last).payload };
1498            assert_eq!(
1499                last_value, 4,
1500                "last pointer should point to the maximum element after sorting"
1501            );
1502        }
1503    }
1504
1505    mod memory_leaks {
1506        use super::*;
1507        use drop_tracker::DropTracker;
1508
1509        #[test]
1510        fn test_memory_leaks() {
1511            let mut tracker = DropTracker::new();
1512
1513            let mut list = SinglyLinkedList::new();
1514            for i in 0..100 {
1515                list.push(tracker.track(i));
1516            }
1517            for i in 100..111 {
1518                list.push_front(tracker.track(i));
1519            }
1520
1521            assert_eq!(tracker.alive().count(), 111);
1522
1523            drop(list);
1524
1525            assert_eq!(tracker.alive().count(), 0);
1526            assert_eq!(tracker.dropped().count(), 111);
1527        }
1528
1529        #[test]
1530        fn test_iterators_with_drop_tracker() {
1531            let mut tracker = DropTracker::new();
1532
1533            let mut list = SinglyLinkedList::new();
1534            for i in 0..5 {
1535                list.push(tracker.track(i));
1536            }
1537
1538            assert_eq!(tracker.alive().count(), 5);
1539
1540            // Use all types of iterators sequentially
1541            {
1542                // Итератор по ссылкам
1543                let ref_count: usize = list.iter().count();
1544                assert_eq!(ref_count, 5);
1545            }
1546            {
1547                // Mutable iterator (modify all elements)
1548                for item in list.iter_mut() {
1549                    **item += 10;
1550                }
1551            }
1552            {
1553                // IntoIterator — take ownership
1554                let collected: Vec<_> = list.into_iter().collect();
1555                assert_eq!(collected, vec![10, 11, 12, 13, 14]);
1556            }
1557
1558            // After IntoIterator the list is destroyed
1559            assert_eq!(tracker.alive().count(), 0);
1560            assert_eq!(tracker.dropped().count(), 5);
1561        }
1562
1563        #[test]
1564        fn test_memory_leaks_with_remove_operations() {
1565            let mut tracker = DropTracker::new();
1566
1567            let mut list = SinglyLinkedList::new();
1568            for i in 0..50 {
1569                list.push(tracker.track(i));
1570            }
1571
1572            assert_eq!(
1573                tracker.alive().count(),
1574                50,
1575                "50 elements should be alive after push"
1576            );
1577
1578            // Removing elements from different positions
1579            assert_eq!(list.remove(0).unwrap(), 0);
1580            assert_eq!(list.remove(48).unwrap(), 49); // last item
1581            assert_eq!(list.remove(24).unwrap(), 25); // middle item
1582
1583            assert_eq!(
1584                tracker.alive().count(),
1585                47,
1586                "After removing 3 elements, 47 should remain alive"
1587            );
1588
1589            // Clear the list completely
1590            while list.len() > 0 {
1591                let _ = list.pop_front();
1592            }
1593
1594            assert_eq!(
1595                tracker.alive().count(),
1596                0,
1597                "All elements should be dropped after clearing the list"
1598            );
1599            assert_eq!(
1600                tracker.dropped().count(),
1601                50,
1602                "All 50 elements should have been dropped"
1603            );
1604        }
1605
1606        #[test]
1607        fn test_memory_leaks_with_insert_operations() {
1608            let mut tracker = DropTracker::new();
1609
1610            let mut list = SinglyLinkedList::new();
1611            list.push(tracker.track(1));
1612            list.push(tracker.track(3));
1613
1614            assert_eq!(
1615                tracker.alive().count(),
1616                2,
1617                "2 elements should be alive initially"
1618            );
1619
1620            // Insert an element into the middle
1621            list.insert(1, tracker.track(2)).unwrap();
1622
1623            assert_eq!(
1624                tracker.alive().count(),
1625                3,
1626                "3 elements should be alive after insert"
1627            );
1628
1629            // Insert at the beginning and end
1630            list.insert(0, tracker.track(0)).unwrap();
1631            list.insert(3, tracker.track(4)).unwrap();
1632
1633            assert_eq!(
1634                tracker.alive().count(),
1635                5,
1636                "5 elements should be alive after all inserts"
1637            );
1638
1639            drop(list);
1640
1641            assert_eq!(
1642                tracker.alive().count(),
1643                0,
1644                "All elements should be dropped when list is dropped"
1645            );
1646            assert_eq!(
1647                tracker.dropped().count(),
1648                5,
1649                "All 5 elements should have been dropped"
1650            );
1651        }
1652
1653        #[test]
1654        fn test_memory_leaks_partial_operations() {
1655            let mut tracker = DropTracker::new();
1656
1657            let mut list = SinglyLinkedList::new();
1658            for i in 0..20 {
1659                list.push(tracker.track(i));
1660            }
1661
1662            assert_eq!(tracker.alive().count(), 20, "20 elements should be alive");
1663
1664            // Perform several deletion and addition operations
1665            for _ in 0..5 {
1666                let _ = list.pop_back();
1667            }
1668            for i in 100..103 {
1669                list.push_front(tracker.track(i));
1670            }
1671
1672            assert!(
1673                tracker.alive().count() < 20,
1674                "Fewer elements should be alive after partial operations"
1675            );
1676
1677            drop(list);
1678
1679            assert_eq!(
1680                tracker.alive().count(),
1681                0,
1682                "All remaining elements should be dropped"
1683            );
1684            assert_eq!(
1685                tracker.dropped().count(),
1686                23,
1687                "Total 23 elements should have been dropped (20 original + 3 added - 5 removed)"
1688            );
1689        }
1690
1691        #[test]
1692        fn test_memory_leaks_with_complex_types() {
1693            let mut tracker = DropTracker::new();
1694
1695            #[derive(Debug, PartialEq, Eq, Hash, Clone)]
1696            struct ComplexStruct {
1697                id: usize,
1698                data: String,
1699            }
1700
1701            impl Drop for ComplexStruct {
1702                fn drop(&mut self) {
1703                    // Just mark the deletion
1704                }
1705            }
1706
1707            let mut list = SinglyLinkedList::new();
1708            for i in 0..15 {
1709                list.push(tracker.track(ComplexStruct {
1710                    id: i,
1711                    data: format!("data_{}", i),
1712                }));
1713            }
1714
1715            assert_eq!(
1716                tracker.alive().count(),
1717                15,
1718                "15 ComplexStruct elements should be alive"
1719            );
1720
1721            // Deleting multiple elements
1722            for _ in 0..3 {
1723                let _ = list.pop_front();
1724            }
1725
1726            assert_eq!(
1727                tracker.alive().count(),
1728                12,
1729                "12 ComplexStruct elements should remain alive"
1730            );
1731
1732            drop(list);
1733
1734            assert_eq!(
1735                tracker.alive().count(),
1736                0,
1737                "All ComplexStruct elements should be dropped"
1738            );
1739            assert_eq!(
1740                tracker.dropped().count(),
1741                15,
1742                "All 15 ComplexStruct elements should have been dropped"
1743            );
1744        }
1745
1746        #[test]
1747        fn test_memory_leaks_error_conditions() {
1748            let mut tracker = DropTracker::new();
1749
1750            let mut list = SinglyLinkedList::new();
1751            for i in 0..10 {
1752                list.push(tracker.track(i));
1753            }
1754
1755            assert_eq!(tracker.alive().count(), 10, "10 elements should be alive");
1756
1757            // Attempted to delete at an invalid index (should not cause leaks)
1758            assert!(list.remove(15).is_err());
1759
1760            // Attempt to insert at invalid index
1761            assert!(list.insert(15, tracker.track(99)).is_err());
1762
1763            assert_eq!(
1764                tracker.alive().count(),
1765                10,
1766                "10 elements should be alive (10 original + 1 attempted insert)"
1767            );
1768
1769            // Clearing the list
1770            while list.len() > 0 {
1771                let _ = list.pop_front();
1772            }
1773
1774            drop(list); // Explicit deletion
1775
1776            assert_eq!(
1777                tracker.alive().count(),
1778                0,
1779                "All elements should be dropped even after error conditions"
1780            );
1781            assert_eq!(
1782                tracker.dropped().count(),
1783                11,
1784                "All 11 elements should have been dropped"
1785            );
1786        }
1787
1788        // Test that clear() properly frees all nodes and there's no memory leak
1789        #[test]
1790        fn test_clear_no_memory_leak_with_drop_tracker() {
1791            // Create a list with tracked nodes
1792            let mut list = SinglyLinkedList::new();
1793            let mut tracker = DropTracker::new();
1794
1795            // Add several elements — each will be wrapped in DropTracker
1796            list.push(tracker.track(10));
1797            list.push(tracker.track(20));
1798            list.push(tracker.track(30));
1799            list.push(tracker.track(40));
1800            list.push(tracker.track(50));
1801
1802            assert_eq!(list.len(), 5, "list should have 5 elements before clear()");
1803            assert_eq!(tracker.alive().count(), 5, "no nodes should be dropped yet");
1804
1805            // Clear the list — all nodes should be freed and their Drop impl called
1806            list.clear();
1807
1808            assert!(list.is_empty(), "list should be empty after clear()");
1809            assert_eq!(list.len(), 0, "length should be 0 after clear()");
1810            assert_eq!(
1811                tracker.alive().count(),
1812                0,
1813                "all 5 nodes should be dropped during clear()"
1814            );
1815
1816            assert_eq!(
1817                tracker.dropped().count(),
1818                5,
1819                "no additional drops should happen after list destruction"
1820            );
1821        }
1822
1823        // Test memory cleanup when clear() is called on a list with complex types
1824        #[test]
1825        fn test_clear_complex_types_no_memory_leak() {
1826            let mut list = SinglyLinkedList::new();
1827            let mut tracker = DropTracker::new();
1828
1829            // Use DropTracker with String type
1830            list.push(tracker.track("first".to_string()));
1831            list.push(tracker.track("second".to_string()));
1832            list.push(tracker.track("third".to_string()));
1833
1834            assert_eq!(list.len(), 3, "complex type list should have correct size");
1835            assert_eq!(tracker.alive().count(), 3, "no drops before clear()");
1836
1837            list.clear();
1838
1839            assert!(
1840                list.is_empty(),
1841                "complex type list should be empty after clear()"
1842            );
1843            assert_eq!(
1844                tracker.alive().count(),
1845                0,
1846                "all 3 complex nodes should be dropped during clear()"
1847            );
1848
1849            assert_eq!(
1850                tracker.dropped().count(),
1851                3,
1852                "no extra drops after complex list destruction"
1853            );
1854        }
1855
1856        // Test that clear() works correctly even if some nodes were already dropped
1857        // through other operations
1858        #[test]
1859        fn test_clear_after_partial_removal_no_leak() {
1860            let mut list = SinglyLinkedList::new();
1861            let mut tracker = DropTracker::new();
1862
1863            // Add 4 elements
1864            list.push(tracker.track(1));
1865            list.push(tracker.track(2));
1866            list.push(tracker.track(3));
1867            list.push(tracker.track(4));
1868
1869            assert_eq!(list.len(), 4, "initial list size should be 4");
1870            assert_eq!(tracker.alive().count(), 4, "no drops at start");
1871
1872            // Remove two elements manually
1873            let _ = list.pop_front(); // drops element 1
1874            let _ = list.pop_back(); // drops element 4
1875
1876            assert_eq!(list.len(), 2, "list size should be 2 after partial removal");
1877            assert_eq!(
1878                tracker.alive().count(),
1879                2,
1880                "2 nodes should be dropped by pop_front and pop_back"
1881            );
1882            assert_eq!(
1883                tracker.dropped().count(),
1884                2,
1885                "2 nodes should be dropped by pop_front and pop_back"
1886            );
1887
1888            // Now clear the remaining two elements
1889            list.clear();
1890
1891            assert!(list.is_empty(), "list should be empty after final clear()");
1892            assert_eq!(
1893                tracker.alive().count(),
1894                0,
1895                "total 4 nodes should be dropped (2 by pop, 2 by clear)"
1896            );
1897
1898            assert_eq!(
1899                tracker.dropped().count(),
1900                4,
1901                "no extra drops after list destruction"
1902            );
1903        }
1904    }
1905}