From 3219b2b8e05a838b85158adcdda832fb8ae28aa9 Mon Sep 17 00:00:00 2001 From: sgoudham Date: Mon, 14 Feb 2022 18:35:54 +0000 Subject: [PATCH] Add a-bad-stack --- linkedlist/a-bad-stack/Cargo.toml | 8 +++ linkedlist/a-bad-stack/src/main.rs | 91 ++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 linkedlist/a-bad-stack/Cargo.toml create mode 100644 linkedlist/a-bad-stack/src/main.rs diff --git a/linkedlist/a-bad-stack/Cargo.toml b/linkedlist/a-bad-stack/Cargo.toml new file mode 100644 index 0000000..0ef4bf4 --- /dev/null +++ b/linkedlist/a-bad-stack/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "a-bad-stack" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/linkedlist/a-bad-stack/src/main.rs b/linkedlist/a-bad-stack/src/main.rs new file mode 100644 index 0000000..b62d36f --- /dev/null +++ b/linkedlist/a-bad-stack/src/main.rs @@ -0,0 +1,91 @@ +#![allow(unused)] + +use std::mem; + +#[derive(Debug)] +pub struct List { + head: Link, +} + +#[derive(Debug)] +enum Link { + Empty, + More(Box), +} + +#[derive(Debug)] +struct Node { + elem: i32, + next: Link, +} + +impl List { + pub fn new() -> Self { + List { head: Link::Empty } + } + + pub fn push(&mut self, elem: i32) { + let new_node = Box::new(Node { + elem, + next: mem::replace(&mut self.head, Link::Empty), + }); + + self.head = Link::More(new_node); + } + + pub fn pop(&mut self) -> Option { + match mem::replace(&mut self.head, Link::Empty) { + Link::Empty => None, + Link::More(node) => { + self.head = node.next; + Some(node.elem) + } + } + } +} + +impl Drop for List { + fn drop(&mut self) { + let mut cur_link = mem::replace(&mut self.head, Link::Empty); + + while let Link::More(mut boxed_node) = cur_link { + cur_link = mem::replace(&mut boxed_node.next, Link::Empty); + } + } +} + +#[cfg(test)] +mod test { + use super::List; + + #[test] + fn basics() { + let mut list = List::new(); + + // Check empty list behaves right + assert_eq!(list.pop(), None); + + // Populate list + list.push(1); + list.push(2); + list.push(3); + + // Check normal removal + assert_eq!(list.pop(), Some(3)); + assert_eq!(list.pop(), Some(2)); + + // Push some more just to make sure nothing's corrupted + list.push(4); + list.push(5); + + // Check normal removal + assert_eq!(list.pop(), Some(5)); + assert_eq!(list.pop(), Some(4)); + + // Check exhaustion + assert_eq!(list.pop(), Some(1)); + assert_eq!(list.pop(), None); + } +} + +fn main() {} \ No newline at end of file