use state_macro::stateful_expr;
use std::cell::RefCell;
use std::rc::Rc;
type State = Rc<RefCell<u8>>;
fn inc(state: State) -> u8 {
let mut i = state.borrow_mut();
*i += 1;
*i
}
fn dec(state: State) -> u8 {
let mut i = state.borrow_mut();
*i = i.saturating_sub(1);
*i
}
fn add(state: State, value: u8) -> u8 {
let mut i = state.borrow_mut();
*i += value;
*i
}
#[stateful_expr(State, state.clone())]
fn test_basic() -> u8 {
::inc() + ::inc()
}
#[test]
fn test_basic_stateful_expr() {
let state = Rc::new(RefCell::new(0u8));
let result = test_basic(state.clone());
assert_eq!(result, 3);
assert_eq!(*state.borrow(), 2);
}
#[stateful_expr(State, state.clone())]
fn test_complex_expr(multiplier: u8) -> u8 {
(::inc() * multiplier) + ::dec()
}
#[test]
fn test_complex_stateful_expr() {
let state = Rc::new(RefCell::new(5u8));
let result = test_complex_expr(state.clone(), 3);
assert_eq!(result, 23);
assert_eq!(*state.borrow(), 5);
}
mod operations {
use super::*;
#[stateful_expr(State, state.clone())]
pub fn increment_and_add(value: u8) -> u8 {
::inc() + ::add(value)
}
}
#[test]
fn test_stateful_expr_with_namespaced_functions() {
let state = Rc::new(RefCell::new(10u8));
let result = operations::increment_and_add(state.clone(), 5);
assert_eq!(result, 27);
assert_eq!(*state.borrow(), 16);
}
#[stateful_expr(State, state.clone())]
fn test_conditional(threshold: u8) -> u8 {
if ::inc() > threshold {
::add(10)
} else {
::add(1)
}
}
#[test]
fn test_stateful_expr_with_conditionals() {
let state1 = Rc::new(RefCell::new(0u8));
let result1 = test_conditional(state1.clone(), 5);
assert_eq!(result1, 2);
assert_eq!(*state1.borrow(), 2);
let state2 = Rc::new(RefCell::new(8u8));
let result2 = test_conditional(state2.clone(), 5);
assert_eq!(result2, 19);
assert_eq!(*state2.borrow(), 19);
}
#[stateful_expr(State, state.clone())]
fn test_block_expr() -> u8 {
({
let first = ::inc();
let second = ::inc();
first * second
}) + ::dec()
}
#[test]
fn test_stateful_expr_with_blocks() {
let state = Rc::new(RefCell::new(2u8));
let result = test_block_expr(state.clone());
assert_eq!(result, 15);
assert_eq!(*state.borrow(), 3);
}