--- a/bindings/jsonnet/src/val_modify.rs +++ b/bindings/jsonnet/src/val_modify.rs @@ -2,11 +2,9 @@ //! Only tested with variables, which haven't altered by code before appearing here //! In jrsonnet every value is immutable, and this code is probally broken -use jrsonnet_evaluator::{ - ArrValue, EvaluationState, LazyBinding, LazyVal, ObjMember, ObjValue, Val, -}; +use jrsonnet_evaluator::{ArrValue, EvaluationState, LazyBinding, LazyVal, ObjMember, Val}; use jrsonnet_parser::Visibility; -use std::{collections::HashMap, ffi::CStr, os::raw::c_char, rc::Rc}; +use std::{ffi::CStr, os::raw::c_char, rc::Rc}; /// # Safety /// @@ -42,8 +40,7 @@ ) { match obj { Val::Obj(old) => { - let mut new = HashMap::new(); - new.insert( + let new_obj = old.clone().extend_with_field( CStr::from_ptr(name).to_str().unwrap().into(), ObjMember { add: false, @@ -52,7 +49,7 @@ location: None, }, ); - let new_obj = ObjValue::new(Some(old.clone()), Rc::new(new)); + *obj = Val::Obj(new_obj); } _ => panic!("should receive object"), --- a/crates/jrsonnet-evaluator/src/obj.rs +++ b/crates/jrsonnet-evaluator/src/obj.rs @@ -3,7 +3,7 @@ use jrsonnet_parser::{ExprLocation, Visibility}; use rustc_hash::FxHashMap; use std::hash::{Hash, Hasher}; -use std::{cell::RefCell, fmt::Debug, rc::Rc}; +use std::{cell::RefCell, fmt::Debug, hash::BuildHasherDefault, rc::Rc}; #[derive(Debug)] pub struct ObjMember { @@ -169,6 +169,13 @@ pub fn get(&self, key: IStr) -> Result> { self.get_raw(key, self.0.this_obj.as_ref()) } + + pub fn extend_with_field(self, key: IStr, value: ObjMember) -> Self { + let mut new = FxHashMap::with_capacity_and_hasher(1, BuildHasherDefault::default()); + new.insert(key, value); + ObjValue::new(Some(self), Rc::new(new)) + } + pub(crate) fn get_raw(&self, key: IStr, real_this: Option<&Self>) -> Result> { let real_this = real_this.unwrap_or(self); let cache_key = (key.clone(), real_this.clone());