git.delta.rocks / jrsonnet / refs/commits / d76beb28c515

difftreelog

feat object destructuring defaults

Yaroslav Bolyukin2022-06-03parent: #3961a53.patch.diff
in: master

5 files changed

modifiedcrates/jrsonnet-evaluator/src/dynamic.rsdiffbeforeafterboth
8 pub fn new() -> Self {8 pub fn new() -> Self {
9 Self(Cc::new(RefCell::new(None)))9 Self(Cc::new(RefCell::new(None)))
10 }10 }
11 pub fn new_filled(v: T) -> Self {
12 Self(Cc::new(RefCell::new(Some(v))))
13 }
11 /// # Panics14 /// # Panics
12 /// If wrapper is filled already15 /// If wrapper is filled already
13 pub fn fill(self, value: T) {16 pub fn fill(self, value: T) {
modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
12};12};
1313
14#[allow(clippy::too_many_lines)]14#[allow(clippy::too_many_lines)]
15#[allow(unused_variables)]
15pub fn destruct(16pub fn destruct(
16 d: &Destruct,17 d: &Destruct,
17 parent: Thunk<Val>,18 parent: Thunk<Val>,
19 fctx: Pending<Context>,
18 new_bindings: &mut GcHashMap<IStr, Thunk<Val>>,20 new_bindings: &mut GcHashMap<IStr, Thunk<Val>>,
19) -> Result<()> {21) -> Result<()> {
20 match d {22 match d {
89 full: full.clone(),91 full: full.clone(),
90 index: i,92 index: i,
91 })),93 })),
94 fctx.clone(),
92 new_bindings,95 new_bindings,
93 )?;96 )?;
94 }97 }
119 start: start.len(),122 start: start.len(),
120 end: end.len(),123 end: end.len(),
121 })),124 })),
125 fctx.clone(),
122 new_bindings,126 new_bindings,
123 )?;127 )?;
124 }128 }
151 index: i,155 index: i,
152 end: end.len(),156 end: end.len(),
153 })),157 })),
158 fctx.clone(),
154 new_bindings,159 new_bindings,
155 )?;160 )?;
156 }161 }
191 }196 }
192 let field_names: Vec<_> = fields.iter().map(|f| f.0.clone()).collect();197 let field_names: Vec<_> = fields
198 .iter()
199 .filter(|f| f.2.is_none())
200 .map(|f| f.0.clone())
201 .collect();
193 let full = Thunk::new(tb!(DataThunk {202 let full = Thunk::new(tb!(DataThunk {
196 has_rest: rest.is_some()205 has_rest: rest.is_some()
197 }));206 }));
198207
199 for (field, d) in fields {208 for (field, d, default) in fields {
200 #[derive(Trace)]209 #[derive(Trace)]
201 struct FieldThunk {210 struct FieldThunk {
202 full: Thunk<ObjValue>,211 full: Thunk<ObjValue>,
203 field: IStr,212 field: IStr,
213 default: Option<(Pending<Context>, LocExpr)>,
204 }214 }
205 impl ThunkValue for FieldThunk {215 impl ThunkValue for FieldThunk {
206 type Output = Val;216 type Output = Val;
207217
208 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {218 fn get(self: Box<Self>, s: State) -> Result<Self::Output> {
209 let full = self.full.evaluate(s.clone())?;219 let full = self.full.evaluate(s.clone())?;
210 let field = full.get(s, self.field)?.expect("shape is checked");220 if let Some(field) = full.get(s.clone(), self.field)? {
211 Ok(field)221 Ok(field)
222 } else {
223 let (fctx, expr) = self.default.as_ref().expect("shape is checked");
224 Ok(evaluate(s, fctx.clone().unwrap(), &expr)?)
225 }
212 }226 }
213 }227 }
214 let value = Thunk::new(tb!(FieldThunk {228 let value = Thunk::new(tb!(FieldThunk {
215 full: full.clone(),229 full: full.clone(),
216 field: field.clone()230 field: field.clone(),
231 default: default.clone().map(|e| (fctx.clone(), e)),
217 }));232 }));
218 if let Some(d) = d {233 if let Some(d) = d {
219 destruct(d, value, new_bindings)?;234 destruct(d, value, fctx.clone(), new_bindings)?;
220 } else {235 } else {
221 destruct(&Destruct::Full(field.clone()), value, new_bindings)?;236 destruct(
237 &Destruct::Full(field.clone()),
238 value,
239 fctx.clone(),
240 new_bindings,
241 )?;
222 }242 }
223 }243 }
251 }271 }
252 let data = Thunk::new(tb!(EvaluateThunkValue {272 let data = Thunk::new(tb!(EvaluateThunkValue {
253 name: into.name(),273 name: into.name(),
254 fctx,274 fctx: fctx.clone(),
255 expr: value.clone(),275 expr: value.clone(),
256 }));276 }));
257 destruct(into, data, new_bindings)?;277 destruct(into, data, fctx, new_bindings)?;
258 }278 }
259 BindSpec::Function {279 BindSpec::Function {
260 name,280 name,
modifiedcrates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth
59 destruct(&name, arg, &mut passed_args)?;59 destruct(
60 &name,
61 arg,
62 Pending::new_filled(ctx.clone()),
63 &mut passed_args,
64 )?;
60 filled_positionals += 1;65 filled_positionals += 1;
61 Ok(())66 Ok(())
96 name: param.0.name().unwrap_or_else(|| "<destruct>".into()),101 name: param.0.name().unwrap_or_else(|| "<destruct>".into()),
97 value: param.1.clone().expect("default exists"),102 value: param.1.clone().expect("default exists"),
98 })),103 })),
104 fctx.clone(),
99 &mut defaults,105 &mut defaults,
100 )?;106 )?;
101 if param.0.name().is_some() {107 if param.0.name().is_some() {
230 name: param.0.name().unwrap_or_else(|| "<destruct>".into()),236 name: param.0.name().unwrap_or_else(|| "<destruct>".into()),
231 value: v.clone(),237 value: v.clone(),
232 })),238 })),
239 fctx.clone(),
233 &mut bindings,240 &mut bindings,
234 )?;241 )?;
235 } else {242 } else {
238 Thunk::new(tb!(DependsOnUnbound(245 Thunk::new(tb!(DependsOnUnbound(
239 param.0.name().unwrap_or_else(|| "<destruct>".into())246 param.0.name().unwrap_or_else(|| "<destruct>".into())
240 ))),247 ))),
248 fctx.clone(),
241 &mut bindings,249 &mut bindings,
242 )?;250 )?;
243 }251 }
modifiedcrates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth
188}188}
189189
190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
191#[derive(Debug, Clone, PartialEq, Eq, Trace)]191#[derive(Debug, Clone, PartialEq, Trace)]
192pub enum Destruct {192pub enum Destruct {
193 Full(IStr),193 Full(IStr),
194 #[cfg(feature = "exp-destruct")]194 #[cfg(feature = "exp-destruct")]
201 },201 },
202 #[cfg(feature = "exp-destruct")]202 #[cfg(feature = "exp-destruct")]
203 Object {203 Object {
204 fields: Vec<(IStr, Option<Destruct>)>,204 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,
205 rest: Option<DestructRest>,205 rest: Option<DestructRest>,
206 },206 },
207}207}
modifiedcrates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth
1#![allow(clippy::redundant_closure_call)]1#![allow(clippy::redundant_closure_call, clippy::derive_partial_eq_without_eq)]
22
3use std::rc::Rc;3use std::rc::Rc;
44
109 }109 }
110 pub rule destruct_object(s: &ParserSettings) -> expr::Destruct110 pub rule destruct_object(s: &ParserSettings) -> expr::Destruct
111 = "{" _111 = "{" _
112 fields:(name:id() _ into:(":" _ into:destruct(s) {into})? {(name, into)})**comma()112 fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default)})**comma()
113 rest:(113 rest:(
114 comma() rest:destruct_rest()? {rest}114 comma() rest:destruct_rest()? {rest}
115 / comma()? {None}115 / comma()? {None}