use std::any::TypeId;
use std::ops::Deref;
use vortex_array::arrays::StructArray;
use vortex_array::{ArrayRef, IntoArray};
use crate::scope_vars::{ScopeVar, ScopeVars};
#[derive(Clone)]
pub struct Scope {
root: ArrayRef,
scope_vars: ScopeVars,
}
impl Scope {
pub fn new(root: ArrayRef) -> Self {
Self {
root,
scope_vars: Default::default(),
}
}
pub fn empty(len: usize) -> Self {
Self::new(StructArray::new_fieldless_with_len(len).into_array())
}
pub fn root(&self) -> &ArrayRef {
&self.root
}
pub fn with_scope_var<V: ScopeVar>(mut self, var: V) -> Self {
self.scope_vars.insert(TypeId::of::<V>(), Box::new(var));
self
}
pub fn scope_var<V: ScopeVar>(&self) -> Option<&V> {
self.scope_vars
.get(&TypeId::of::<V>())
.and_then(|boxed| (**boxed).as_any().downcast_ref::<V>())
}
pub fn scope_var_mut<V: ScopeVar>(&mut self) -> Option<&mut V> {
self.scope_vars
.get_mut(&TypeId::of::<V>())
.and_then(|boxed| (**boxed).as_any_mut().downcast_mut::<V>())
}
}
impl Deref for Scope {
type Target = ArrayRef;
fn deref(&self) -> &Self::Target {
&self.root
}
}
impl From<ArrayRef> for Scope {
fn from(value: ArrayRef) -> Self {
Self::new(value)
}
}
#[cfg(test)]
mod test {
#[test]
fn test_scope_var() {
use super::*;
#[derive(Clone, PartialEq, Eq, Debug)]
struct TestVar {
value: i32,
}
let scope = Scope::empty(100);
assert!(scope.scope_var::<TestVar>().is_none());
let var = TestVar { value: 42 };
let mut scope = scope.with_scope_var(var.clone());
assert_eq!(scope.scope_var::<TestVar>(), Some(&var));
scope.scope_var_mut::<TestVar>().unwrap().value = 43;
assert_eq!(scope.scope_var::<TestVar>(), Some(&TestVar { value: 43 }));
}
}