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

difftreelog

source

crates/jsonnet-evaluator/src/obj.rs2.1 KiBsourcehistory
1use crate::{dummy_debug, evaluate_binary_op, BoxedBinding, Val};2use jsonnet_parser::{BinaryOpType, Visibility};3use std::{4	collections::{BTreeMap, BTreeSet},5	rc::Rc,6};78#[derive(Debug)]9pub struct ObjMember {10	pub add: bool,11	pub visibility: Visibility,12	pub invoke: BoxedBinding,13}1415#[derive(Debug)]16pub struct ObjValueInternals {17	super_obj: Option<ObjValue>,18	this_entries: Rc<BTreeMap<String, ObjMember>>,19}20pub struct ObjValue(Rc<ObjValueInternals>);21dummy_debug!(ObjValue);22impl ObjValue {23	pub fn new(24		super_obj: Option<ObjValue>,25		this_entries: Rc<BTreeMap<String, ObjMember>>,26	) -> ObjValue {27		ObjValue(Rc::new(ObjValueInternals {28			super_obj,29			this_entries,30		}))31	}32	pub fn with_super(&self, super_obj: ObjValue) -> ObjValue {33		match &self.0.super_obj {34			None => ObjValue::new(Some(super_obj), self.0.this_entries.clone()),35			Some(v) => ObjValue::new(Some(v.with_super(super_obj)), self.0.this_entries.clone()),36		}37	}38	pub fn fields(&self) -> BTreeSet<String> {39		let mut fields = BTreeSet::new();40		self.0.this_entries.keys().for_each(|k| {41			fields.insert(k.clone());42		});43		if self.0.super_obj.is_some() {44			for field in self.0.super_obj.clone().unwrap().fields() {45				fields.insert(field);46			}47		}48		fields49	}50	pub fn get_raw(&self, key: &str, real_this: Option<ObjValue>) -> Option<Val> {51		match (self.0.this_entries.get(key), &self.0.super_obj) {52			(Some(k), None) => Some(k.invoke.evaluate(53				real_this.or_else(|| Some(self.clone())),54				self.0.super_obj.clone().map(|e| e.clone()),55			)),56			(Some(k), Some(s)) => {57				let our = k58					.invoke59					.evaluate(Some(self.clone()), self.0.super_obj.clone());60				if k.add {61					s.get_raw(key, Some(self.clone()))62						.map_or(Some(our.clone()), |v| {63							Some(evaluate_binary_op(&v, BinaryOpType::Add, &our))64						})65				} else {66					Some(our)67				}68			}69			(None, Some(s)) => s.get_raw(key, Some(self.clone())),70			(None, None) => None,71		}72	}73}74impl Clone for ObjValue {75	fn clone(&self) -> Self {76		ObjValue(self.0.clone())77	}78}79impl PartialEq for ObjValue {80	fn eq(&self, other: &Self) -> bool {81		Rc::ptr_eq(&self.0, &other.0)82	}83}