diff --git a/libs/Forc.toml b/libs/Forc.toml index d7e30125..e6a50814 100644 --- a/libs/Forc.toml +++ b/libs/Forc.toml @@ -7,6 +7,7 @@ members = [ "queue", "reentrancy", "signed_integers", + "stack", "storagemapvec", "strings/storage_string", "strings/string", diff --git a/libs/stack/.gitignore b/libs/stack/.gitignore new file mode 100644 index 00000000..77d3844f --- /dev/null +++ b/libs/stack/.gitignore @@ -0,0 +1,2 @@ +out +target diff --git a/libs/stack/Forc.toml b/libs/stack/Forc.toml new file mode 100644 index 00000000..a9b3ec08 --- /dev/null +++ b/libs/stack/Forc.toml @@ -0,0 +1,7 @@ +[project] +authors = ["Fuel Labs "] +entry = "main.sw" +license = "Apache-2.0" +name = "stack" + +[dependencies] diff --git a/libs/stack/src/main.sw b/libs/stack/src/main.sw new file mode 100644 index 00000000..45eaf117 --- /dev/null +++ b/libs/stack/src/main.sw @@ -0,0 +1,143 @@ +library; +//! The `Stack` type corresponds to the same called data structure. +//! A Stack is defined as a linear data structure that is open at the only ends and the operations are performed in Last In First Out order. + +pub struct Stack { + vec: Vec, +} + +impl Stack { + pub fn new() -> Self { + Self { + vec: Vec::new(), + } + } + + pub fn is_empty(self) -> bool { + self.vec.is_empty() + } + + pub fn len(self) -> u64 { + self.vec.len() + } + + pub fn push(ref mut self, value: T) { + self.vec.push(value); + } + + pub fn pop(ref mut self) -> Option { + self.vec.pop() + } + + pub fn peek(self) -> Option { + if self.vec.is_empty() { + Option::None + } else { + self.vec.get(self.vec.len() - 1) + } + } +} + +#[test] +fn test_new_stack_is_empty() { + let stack: Stack = Stack::new(); + assert(stack.is_empty()); +} + +#[test] +fn test_push_single_element() { + let mut stack = Stack::new(); + stack.push(42); + + assert(stack.len() == 1); + std::logging::log(stack.len()); + std::logging::log(stack.vec.get(0).unwrap()); + assert(!stack.is_empty()); +} + +#[test] +fn test_push_multiple_elements() { + let mut stack = Stack::new(); + stack.push(1); + stack.push(2); + stack.push(3); + assert(stack.len() == 3); + assert(!stack.is_empty()); +} + +#[test] +fn test_pop_empty_stack() { + let mut stack: Stack = Stack::new(); + let popped = stack.pop(); + assert(popped.is_none()); + assert(stack.len() == 0); + assert(stack.is_empty()); +} + +#[test] +fn test_pop_single_element() { + let mut stack = Stack::new(); + stack.push(42); + let popped = stack.pop(); + assert(popped.unwrap() == 42); + assert(stack.len() == 0); + assert(stack.is_empty()); +} + +#[test] +fn test_pop_multiple_elements() { + let mut stack = Stack::new(); + stack.push(1); + stack.push(2); + stack.push(3); + let popped1 = stack.pop(); + assert(popped1.unwrap() == 3); + assert(stack.len() == 2); + assert(!stack.is_empty()); + + let popped2 = stack.pop(); + assert(popped2.unwrap() == 2); + assert(stack.len() == 1); + assert(!stack.is_empty()); + + let popped3 = stack.pop(); + assert(popped3.unwrap() == 1); + assert(stack.len() == 0); + assert(stack.is_empty()); + + let popped4 = stack.pop(); + assert(popped4.is_none()); + assert(stack.len() == 0); + assert(stack.is_empty()); +} + +#[test] +fn test_peek_empty_stack() { + let stack: Stack = Stack::new(); + let peeked = stack.peek(); + assert(peeked.is_none()); + assert(stack.len() == 0); + assert(stack.is_empty()); +} + +#[test] +fn test_peek_single_element() { + let mut stack = Stack::new(); + stack.push(42); + let peeked = stack.peek(); + assert(peeked.unwrap() == 42); + assert(stack.len() == 1); + assert(!stack.is_empty()); +} + +#[test] +fn test_peek_multiple_elements() { + let mut stack = Stack::new(); + stack.push(1); + stack.push(2); + stack.push(3); + let peeked = stack.peek(); + assert(peeked.unwrap() == 3); + assert(stack.len() == 3); + assert(!stack.is_empty()); +}