use bumpalo::Bump;
use datavalue::OwnedDataValue;
use crate::arena::DataValue;
use crate::{Engine, EvalInput, Logic, Result};
pub struct Session<'engine> {
engine: &'engine Engine,
arena: Bump,
}
impl std::fmt::Debug for Session<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Session")
.field("engine", &self.engine)
.field("arena_allocated_bytes", &self.arena.allocated_bytes())
.finish_non_exhaustive()
}
}
impl<'engine> Session<'engine> {
#[inline]
pub(crate) fn new(engine: &'engine Engine) -> Self {
Self {
engine,
arena: Bump::new(),
}
}
#[inline]
pub fn reset(&mut self) {
self.arena.reset();
}
pub fn reset_with_capacity(&mut self, capacity: usize) {
self.arena = Bump::with_capacity(capacity);
}
#[inline]
pub fn allocated_bytes(&self) -> usize {
self.arena.allocated_bytes()
}
pub fn eval<'a, D>(&'a mut self, compiled: &Logic, data: D) -> Result<OwnedDataValue>
where
D: EvalInput<'a>,
{
let arena: &'a Bump = &self.arena;
let av = data.into_arena_value(arena)?;
let result = self.engine.evaluate(compiled, av, arena)?;
crate::FromDataValue::from_arena(result)
}
pub fn eval_str<'a, D>(&'a mut self, compiled: &Logic, data: D) -> Result<String>
where
D: EvalInput<'a>,
{
let arena: &'a Bump = &self.arena;
let av = data.into_arena_value(arena)?;
let result = self.engine.evaluate(compiled, av, arena)?;
crate::FromDataValue::from_arena(result)
}
#[cfg(feature = "serde_json")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde_json")))]
pub fn eval_into<'a, T, D>(&'a mut self, compiled: &Logic, data: D) -> Result<T>
where
T: serde::de::DeserializeOwned,
D: EvalInput<'a>,
{
let value: serde_json::Value = {
let arena: &'a Bump = &self.arena;
let av = data.into_arena_value(arena)?;
let result = self.engine.evaluate(compiled, av, arena)?;
crate::FromDataValue::from_arena(result)?
};
serde_json::from_value(value).map_err(crate::Error::from)
}
pub fn eval_borrowed<'a, D>(
&'a mut self,
compiled: &'a Logic,
data: D,
) -> Result<&'a DataValue<'a>>
where
D: EvalInput<'a>,
{
let arena: &'a Bump = &self.arena;
let av = data.into_arena_value(arena)?;
self.engine.evaluate(compiled, av, arena)
}
}