use std::cell::RefCell;
use std::rc::Rc;
use arora_types::data::Slot;
use arora_types::value::Value;
#[derive(Clone)]
pub enum VariableCell {
Local(Rc<RefCell<Option<Value>>>),
Stored(Rc<dyn Slot>),
}
impl std::fmt::Debug for VariableCell {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("VariableCell").field(&self.get()).finish()
}
}
impl PartialEq for VariableCell {
fn eq(&self, other: &Self) -> bool {
self.get() == other.get()
}
}
impl VariableCell {
pub fn local() -> Self {
VariableCell::Local(Rc::new(RefCell::new(None)))
}
pub fn local_with(value: Value) -> Self {
VariableCell::Local(Rc::new(RefCell::new(Some(value))))
}
pub fn stored(slot: Box<dyn Slot>) -> Self {
VariableCell::Stored(Rc::from(slot))
}
pub fn get(&self) -> Option<Value> {
match self {
VariableCell::Local(cell) => cell.borrow().clone(),
VariableCell::Stored(slot) => slot.get(),
}
}
pub fn get_or_unit(&self) -> Value {
self.get().unwrap_or(Value::Unit)
}
pub fn set(&self, value: Value) {
self.set_opt(Some(value));
}
pub fn set_opt(&self, value: Option<Value>) {
match self {
VariableCell::Local(cell) => *cell.borrow_mut() = value,
VariableCell::Stored(slot) => {
let _ = slot.set(value);
}
}
}
}
pub type VariableResolver<'a> = dyn Fn(&str) -> Option<Box<dyn Slot>> + 'a;