use state_macro::{stateful, with_state};
use std::cell::RefCell;
use std::rc::Rc;
type StackState = Rc<RefCell<Vec<i32>>>;
fn new_stack() -> StackState {
Rc::new(RefCell::new(Vec::new()))
}
fn push(state: &StackState, value: i32) {
state.borrow_mut().push(value);
}
fn pop(state: &StackState) -> i32 {
state.borrow_mut().pop().unwrap_or(0)
}
fn get_len(state: &StackState) -> usize {
state.borrow().len()
}
#[stateful(&StackState)]
fn add() {
if ::get_len() >= 2 {
let (a, b) = (::pop(), ::pop());
::push(a + b);
}
}
fn stack_sum_with_state(state: &StackState, values: &[i32]) -> i32 {
with_state! { state;
for value in values {
::push(*value);
}
while ::get_len() >= 2 {
::add();
}
::pop()
}
}
#[stateful(&StackState)]
fn stack_sum_stateful(values: &[i32]) -> i32 {
for value in values {
::push(*value);
}
while ::get_len() >= 2 {
::add();
}
::pop()
}
fn main() {
let values = [1, 2, 3, 4, 5];
let stack1 = new_stack();
let result1 = stack_sum_with_state(&stack1, &values);
println!("Result using with_state! macro: {}", result1);
let stack2 = new_stack();
let result2 = stack_sum_stateful(&stack2, &values);
println!("Result using #[stateful] attribute: {}", result2);
assert_eq!(result2, 15);
let stack3 = new_stack();
println!("\nDetailed stack operations demonstration:");
push(&stack3, 10);
println!("Pushed 10, stack: {:?}", stack3.borrow());
push(&stack3, 20);
println!("Pushed 20, stack: {:?}", stack3.borrow());
add(&stack3);
println!("Added top two elements, stack: {:?}", stack3.borrow());
let result = pop(&stack3);
println!("Popped result: {}, stack: {:?}", result, stack3.borrow());
}