git.delta.rocks / jrsonnet / refs/commits / 2e6febe0ffcd

difftreelog

source

crates/jsonnet-evaluator/src/ctx.rs2.4 KiBsourcehistory
1use crate::{future_wrapper, rc_fn_helper, Binding, ObjValue};2use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};34rc_fn_helper!(5	ContextCreator,6	context_creator,7	dyn Fn(Option<ObjValue>, Option<ObjValue>) -> Context8);910future_wrapper!(Context, FutureContext);1112#[derive(Debug)]13struct ContextInternals {14	dollar: Option<ObjValue>,15	this: Option<ObjValue>,16	super_obj: Option<ObjValue>,17	bindings: Rc<RefCell<HashMap<String, Binding>>>,18}19pub struct Context(Rc<ContextInternals>);20impl Debug for Context {21	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {22		f.debug_struct("Context")23			.field("this", &self.0.this.clone().map(|e| Rc::as_ptr(&e.0)))24			.finish()25	}26}27impl Context {28	pub fn new_future() -> FutureContext {29		FutureContext(Rc::new(RefCell::new(None)))30	}3132	pub fn dollar(&self) -> &Option<ObjValue> {33		&self.0.dollar34	}3536	pub fn this(&self) -> &Option<ObjValue> {37		&self.0.this38	}3940	pub fn super_obj(&self) -> &Option<ObjValue> {41		&self.0.super_obj42	}4344	pub fn new() -> Context {45		Context(Rc::new(ContextInternals {46			dollar: None,47			this: None,48			super_obj: None,49			bindings: Rc::new(RefCell::new(HashMap::new())),50		}))51	}5253	pub fn binding(&self, name: &str) -> Binding {54		self.055			.bindings56			.borrow()57			.get(name)58			.cloned()59			.unwrap_or_else(|| {60				panic!("can't find {} in {:?}", name, self);61			})62	}63	pub fn into_future(self, ctx: FutureContext) -> Context {64		{65			ctx.0.borrow_mut().replace(self);66		}67		ctx.unwrap()68	}6970	pub fn extend(71		&self,72		new_bindings: HashMap<String, Binding>,73		new_dollar: Option<ObjValue>,74		new_this: Option<ObjValue>,75		new_super_obj: Option<ObjValue>,76	) -> Context {77		let dollar = new_dollar.or_else(|| self.0.dollar.clone());78		let this = new_this.or_else(|| self.0.this.clone());79		let super_obj = new_super_obj.or_else(|| self.0.super_obj.clone());80		let bindings = if new_bindings.is_empty() {81			self.0.bindings.clone()82		} else {83			let new = self.0.bindings.clone();84			for (k, v) in new_bindings.into_iter() {85				new.borrow_mut().insert(k, v);86			}87			new88		};89		Context(Rc::new(ContextInternals {90			dollar,91			this,92			super_obj,93			bindings,94		}))95	}96}9798impl Default for Context {99	fn default() -> Self {100		Self::new()101	}102}103104impl PartialEq for Context {105	fn eq(&self, other: &Self) -> bool {106		Rc::ptr_eq(&self.0, &other.0)107	}108}109110impl Clone for Context {111	fn clone(&self) -> Self {112		Context(self.0.clone())113	}114}