git.delta.rocks / jrsonnet / refs/commits / 078724755e3c

difftreelog

source

crates/jsonnet-evaluator/src/ctx.rs2.5 KiBsourcehistory
1use crate::{dummy_debug, future_wrapper, BoxedBinding, ObjValue};2use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};34pub trait ContextCreator: Debug {5	fn create_context(&self, this: &Option<ObjValue>, super_obj: &Option<ObjValue>) -> Context;6}7pub type BoxedContextCreator = Rc<dyn ContextCreator>;89#[derive(Debug)]10pub struct ConstantContextCreator {11	pub context: FutureContext,12}13impl ContextCreator for ConstantContextCreator {14	fn create_context(&self, _this: &Option<ObjValue>, _super_obj: &Option<ObjValue>) -> Context {15		self.context.clone().unwrap()16	}17}1819future_wrapper!(Context, FutureContext);2021#[derive(Debug)]22struct ContextInternals {23	dollar: Option<ObjValue>,24	this: Option<ObjValue>,25	super_obj: Option<ObjValue>,26	bindings: Rc<RefCell<HashMap<String, BoxedBinding>>>,27}28pub struct Context(Rc<ContextInternals>);29dummy_debug!(Context);30impl Context {31	pub fn new_future() -> FutureContext {32		FutureContext(Rc::new(RefCell::new(None)))33	}3435	pub fn dollar(&self) -> &Option<ObjValue> {36		&self.0.dollar37	}3839	pub fn this(&self) -> &Option<ObjValue> {40		&self.0.this41	}4243	pub fn super_obj(&self) -> &Option<ObjValue> {44		&self.0.super_obj45	}4647	pub fn new() -> Context {48		Context(Rc::new(ContextInternals {49			dollar: None,50			this: None,51			super_obj: None,52			bindings: Rc::new(RefCell::new(HashMap::new())),53		}))54	}5556	pub fn binding(&self, name: &str) -> BoxedBinding {57		self.058			.bindings59			.borrow()60			.get(name)61			.map(|e| e.clone())62			.unwrap_or_else(|| {63				panic!("can't find {} in {:?}", name, self);64			})65	}66	pub fn into_future(self, ctx: FutureContext) -> Context {67		{68			ctx.0.borrow_mut().replace(self);69		}70		ctx.unwrap()71	}7273	pub fn extend(74		&self,75		new_bindings: HashMap<String, BoxedBinding>,76		new_dollar: Option<ObjValue>,77		new_this: Option<ObjValue>,78		new_super_obj: Option<ObjValue>,79	) -> Context {80		let dollar = new_dollar.or(self.0.dollar.clone());81		let this = new_this.or(self.0.this.clone());82		let super_obj = new_super_obj.or(self.0.super_obj.clone());83		let bindings = if new_bindings.is_empty() {84			self.0.bindings.clone()85		} else {86			let new = self.0.bindings.clone();87			for (k, v) in new_bindings.into_iter() {88				new.borrow_mut().insert(k, v);89			}90			new91		};92		Context(Rc::new(ContextInternals {93			dollar,94			this,95			super_obj,96			bindings,97		}))98	}99}100impl PartialEq for Context {101	fn eq(&self, other: &Self) -> bool {102		Rc::ptr_eq(&self.0, &other.0)103	}104}105106impl Clone for Context {107	fn clone(&self) -> Self {108		Context(self.0.clone())109	}110}