use std::sync::Arc;
use vantage_core::Result;
use vantage_rhai::Vocab;
use vantage_rhai::rhai::Engine;
use super::narrow::register_narrowing;
use super::read::register_reads;
use super::record::register_record;
use super::write::register_writes;
use crate::vista::Vista;
pub type TargetResolver = Arc<dyn Fn(&str) -> Result<Vista> + Send + Sync>;
#[derive(Clone)]
pub enum Writes {
Allowed,
Denied(String),
}
#[derive(Clone)]
pub enum Terminals {
Describe,
Read { limit: Option<usize> },
ReadWrite {
limit: Option<usize>,
writes: Writes,
},
}
#[derive(Clone)]
pub struct DataVocab {
pub resolver: Option<TargetResolver>,
pub terminals: Terminals,
}
impl DataVocab {
pub fn describe(resolver: Option<TargetResolver>) -> Self {
Self {
resolver,
terminals: Terminals::Describe,
}
}
pub fn read(resolver: Option<TargetResolver>, limit: Option<usize>) -> Self {
Self {
resolver,
terminals: Terminals::Read { limit },
}
}
pub fn read_write(resolver: Option<TargetResolver>) -> Self {
Self::read_write_with(resolver, None, Writes::Allowed)
}
pub fn read_write_with(
resolver: Option<TargetResolver>,
limit: Option<usize>,
writes: Writes,
) -> Self {
Self {
resolver,
terminals: Terminals::ReadWrite { limit, writes },
}
}
}
impl Vocab for DataVocab {
fn register(&self, engine: &mut Engine) {
register_narrowing(engine, self.resolver.clone());
match &self.terminals {
Terminals::Describe => {}
Terminals::Read { limit } => {
register_reads(engine, self.resolver.clone(), *limit);
register_record(
engine,
self.resolver.clone(),
Writes::Denied("writes aren't available here".to_string()),
);
}
Terminals::ReadWrite { limit, writes } => {
register_reads(engine, self.resolver.clone(), *limit);
register_writes(engine, self.resolver.clone(), writes.clone());
register_record(engine, self.resolver.clone(), writes.clone());
}
}
}
}