difftreelog
refactor object builder
in: master
3 files changed
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth2 error::Error::*,2 error::Error::*,3 evaluate::operator::{evaluate_add_op, evaluate_binary_op_special, evaluate_unary_op},3 evaluate::operator::{evaluate_add_op, evaluate_binary_op_special, evaluate_unary_op},4 push, throw, with_state, ArrValue, Bindable, Context, ContextCreator, FuncDesc, FuncVal,4 push, throw, with_state, ArrValue, Bindable, Context, ContextCreator, FuncDesc, FuncVal,5 FutureWrapper, LazyBinding, LazyVal, LazyValValue, ObjMember, ObjValue, ObjectAssertion,5 FutureWrapper, LazyBinding, LazyVal, LazyValValue, ObjValue, ObjValueBuilder, ObjectAssertion,6 Result, Val,6 Result, Val,7};7};8use jrsonnet_gc::{Gc, Trace};8use jrsonnet_gc::{Gc, Trace};9use jrsonnet_interner::IStr;9use jrsonnet_interner::IStr;10use jrsonnet_parser::{10use jrsonnet_parser::{11 ArgsDesc, AssertStmt, BindSpec, CompSpec, Expr, ExprLocation, FieldMember, ForSpecData,11 ArgsDesc, AssertStmt, BindSpec, CompSpec, Expr, ExprLocation, FieldMember, ForSpecData,12 IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc, Visibility,12 IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc,13};13};14use jrsonnet_types::ValType;14use jrsonnet_types::ValType;15use rustc_hash::{FxHashMap, FxHasher};15use rustc_hash::{FxHashMap, FxHasher};254 new_bindings.fill(bindings);254 new_bindings.fill(bindings);255 }255 }256256257 let mut new_members = FxHashMap::default();258 let mut assertions: Vec<Box<dyn ObjectAssertion>> = Vec::new();257 let mut builder = ObjValueBuilder::new();259 for member in members.iter() {258 for member in members.iter() {260 match member {259 match member {261 Member::Field(FieldMember {260 Member::Field(FieldMember {291 )?))290 )?))292 }291 }293 }292 }293 builder294 new_members.insert(294 .member(name.clone())295 name.clone(),296 ObjMember {297 add: *plus,295 .with_add(*plus)298 visibility: *visibility,296 .with_visibility(*visibility)297 .with_location(value.1.clone())299 invoke: LazyBinding::Bindable(Gc::new(Box::new(ObjMemberBinding {298 .bindable(Box::new(ObjMemberBinding {300 context_creator: context_creator.clone(),299 context_creator: context_creator.clone(),301 value: value.clone(),300 value: value.clone(),302 name,301 name,303 }))),302 }));304 location: value.1.clone(),305 },306 );307 }303 }308 Member::Field(FieldMember {304 Member::Field(FieldMember {309 name,305 name,338 )))334 )))339 }335 }340 }336 }337 builder341 new_members.insert(338 .member(name.clone())342 name.clone(),339 .hide()343 ObjMember {340 .with_location(value.1.clone())344 add: false,345 visibility: Visibility::Hidden,346 invoke: LazyBinding::Bindable(Gc::new(Box::new(ObjMemberBinding {341 .binding(LazyBinding::Bindable(Gc::new(Box::new(ObjMemberBinding {347 context_creator: context_creator.clone(),342 context_creator: context_creator.clone(),348 value: value.clone(),343 value: value.clone(),349 params: params.clone(),344 params: params.clone(),350 name,345 name,351 }))),346 }))));352 location: value.1.clone(),353 },354 );355 }347 }356 Member::BindStmt(_) => {}348 Member::BindStmt(_) => {}357 Member::AssertStmt(stmt) => {349 Member::AssertStmt(stmt) => {371 evaluate_assert(ctx, &self.assert)363 evaluate_assert(ctx, &self.assert)372 }364 }373 }365 }374 assertions.push(Box::new(ObjectAssert {366 builder.assert(Box::new(ObjectAssert {375 context_creator: context_creator.clone(),367 context_creator: context_creator.clone(),376 assert: stmt.clone(),368 assert: stmt.clone(),377 }));369 }));378 }370 }379 }371 }380 }372 }381 let this = ObjValue::new(None, Gc::new(new_members), Gc::new(assertions));373 let this = builder.build();382 future_this.fill(this.clone());374 future_this.fill(this.clone());383 Ok(this)375 Ok(this)384}376}388 ObjBody::MemberList(members) => evaluate_member_list_object(context, members)?,380 ObjBody::MemberList(members) => evaluate_member_list_object(context, members)?,389 ObjBody::ObjComp(obj) => {381 ObjBody::ObjComp(obj) => {390 let future_this = FutureWrapper::new();382 let future_this = FutureWrapper::new();391 let mut new_members = FxHashMap::default();383 let mut builder = ObjValueBuilder::new();392 evaluate_comp(context.clone(), &obj.compspecs, &mut |ctx| {384 evaluate_comp(context.clone(), &obj.compspecs, &mut |ctx| {393 let new_bindings = FutureWrapper::new();385 let new_bindings = FutureWrapper::new();394 let context_creator = ContextCreator(context.clone(), new_bindings.clone());386 let context_creator = ContextCreator(context.clone(), new_bindings.clone());435 )?))427 )?))436 }428 }437 }429 }430 builder438 new_members.insert(431 .member(n)439 n,432 .with_location(obj.value.1.clone())440 ObjMember {441 add: false,442 visibility: Visibility::Normal,443 invoke: LazyBinding::Bindable(Gc::new(Box::new(ObjCompBinding {433 .bindable(Box::new(ObjCompBinding {444 context: ctx,434 context: ctx,445 value: obj.value.clone(),435 value: obj.value.clone(),446 }))),436 }));447 location: obj.value.1.clone(),448 },449 );450 }437 }451 v => throw!(FieldMustBeStringGot(v.value_type())),438 v => throw!(FieldMustBeStringGot(v.value_type())),452 }439 }453440454 Ok(())441 Ok(())455 })?;442 })?;456443457 let this = ObjValue::new(None, Gc::new(new_members), Gc::new(Vec::new()));444 let this = builder.build();458 future_this.fill(this.clone());445 future_this.fill(this.clone());459 this446 this460 }447 }crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth1use crate::{1use crate::{2 error::{Error::*, LocError, Result},2 error::{Error::*, LocError, Result},3 throw, LazyBinding, LazyVal, ObjMember, ObjValue, Val,3 throw, ObjValueBuilder, Val,4};4};5use jrsonnet_gc::Gc;6use jrsonnet_parser::Visibility;7use rustc_hash::FxHasher;8use serde_json::{Map, Number, Value};5use serde_json::{Map, Number, Value};9use std::{6use std::convert::{TryFrom, TryInto};10 collections::HashMap,11 convert::{TryFrom, TryInto},12 hash::BuildHasherDefault,13};14715impl TryFrom<&Val> for Value {8impl TryFrom<&Val> for Value {16 type Error = LocError;9 type Error = LocError;54 Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),47 Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),55 Value::String(s) => Self::Str((s as &str).into()),48 Value::String(s) => Self::Str((s as &str).into()),56 Value::Array(a) => {49 Value::Array(a) => {57 let mut out = Vec::with_capacity(a.len());50 let mut out: Vec<Val> = Vec::with_capacity(a.len());58 for v in a {51 for v in a {59 out.push(LazyVal::new_resolved(v.into()));52 out.push(v.into());60 }53 }61 Self::Arr(out.into())54 Self::Arr(out.into())62 }55 }63 Value::Object(o) => {56 Value::Object(o) => {64 let mut entries = HashMap::with_capacity_and_hasher(57 let mut builder = ObjValueBuilder::with_capacity(o.len());65 o.len(),66 BuildHasherDefault::<FxHasher>::default(),67 );68 for (k, v) in o {58 for (k, v) in o {69 entries.insert(59 builder.member((k as &str).into()).value(v.into());70 (k as &str).into(),71 ObjMember {72 add: false,73 visibility: Visibility::Normal,74 invoke: LazyBinding::Bound(LazyVal::new_resolved(v.into())),75 location: None,76 },77 );78 }60 }79 Self::Obj(ObjValue::new(None, Gc::new(entries), Gc::new(Vec::new())))61 Val::Obj(builder.build())80 }62 }81 }63 }82 }64 }crates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth1use crate::operator::evaluate_add_op;1use crate::operator::evaluate_add_op;2use crate::{LazyBinding, Result, Val};2use crate::{Bindable, LazyBinding, LazyVal, Result, Val};3use jrsonnet_gc::{Gc, GcCell, Trace};3use jrsonnet_gc::{Gc, GcCell, Trace};4use jrsonnet_interner::IStr;4use jrsonnet_interner::IStr;5use jrsonnet_parser::{ExprLocation, Visibility};5use jrsonnet_parser::{ExprLocation, Visibility};6use rustc_hash::{FxHashMap, FxHashSet};6use rustc_hash::{FxHashMap, FxHashSet, FxHasher};7use std::collections::HashMap;7use std::hash::{Hash, Hasher};8use std::hash::{Hash, Hasher};8use std::{fmt::Debug, hash::BuildHasherDefault};9use std::{fmt::Debug, hash::BuildHasherDefault};910275 }276 }276}277}278279pub struct ObjValueBuilder {280 super_obj: Option<ObjValue>,281 map: FxHashMap<IStr, ObjMember>,282 assertions: Vec<Box<dyn ObjectAssertion>>,283}284impl ObjValueBuilder {285 pub fn new() -> Self {286 Self::with_capacity(0)287 }288 pub fn with_capacity(capacity: usize) -> Self {289 Self {290 super_obj: None,291 map: HashMap::with_capacity_and_hasher(292 capacity,293 BuildHasherDefault::<FxHasher>::default(),294 ),295 assertions: Vec::new(),296 }297 }298 pub fn reserve_asserts(&mut self, capacity: usize) -> &mut Self {299 self.assertions.reserve_exact(capacity);300 self301 }302 pub fn with_super(&mut self, super_obj: ObjValue) -> &mut Self {303 self.super_obj = Some(super_obj);304 self305 }306307 pub fn assert(&mut self, assertion: Box<dyn ObjectAssertion>) -> &mut Self {308 self.assertions.push(assertion);309 self310 }311 pub fn member(&mut self, name: IStr) -> ObjMemberBuilder {312 ObjMemberBuilder {313 value: self,314 name,315 add: false,316 visibility: Visibility::Normal,317 location: None,318 }319 }320321 pub fn build(self) -> ObjValue {322 ObjValue::new(self.super_obj, Gc::new(self.map), Gc::new(self.assertions))323 }324}325326#[must_use = "value not added unless binding() was called"]327pub struct ObjMemberBuilder<'v> {328 value: &'v mut ObjValueBuilder,329 name: IStr,330 add: bool,331 visibility: Visibility,332 location: Option<ExprLocation>,333}334335impl<'v> ObjMemberBuilder<'v> {336 pub fn with_add(mut self, add: bool) -> Self {337 self.add = add;338 self339 }340 pub fn add(self) -> Self {341 self.with_add(true)342 }343 pub fn with_visibility(mut self, visibility: Visibility) -> Self {344 self.visibility = visibility;345 self346 }347 pub fn hide(self) -> Self {348 self.with_visibility(Visibility::Hidden)349 }350 pub fn with_location(mut self, location: Option<ExprLocation>) -> Self {351 self.location = location;352 self353 }354 pub fn value(self, value: Val) -> &'v mut ObjValueBuilder {355 self.binding(LazyBinding::Bound(LazyVal::new_resolved(value)))356 }357 pub fn bindable(self, bindable: Box<dyn Bindable>) -> &'v mut ObjValueBuilder {358 self.binding(LazyBinding::Bindable(Gc::new(bindable)))359 }360 pub fn binding(self, binding: LazyBinding) -> &'v mut ObjValueBuilder {361 self.value.map.insert(362 self.name,363 ObjMember {364 add: self.add,365 visibility: self.visibility,366 invoke: binding,367 location: self.location,368 },369 );370 self.value371 }372}277373