difftreelog
fix destructure
in: master
4 files changed
crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth142 Ok(field)142 Ok(field)143 } else {143 } else {144 let (fctx, expr) = default.as_ref().expect("shape is checked");144 let (fctx, expr) = default.as_ref().expect("shape is checked");145 Ok(evaluate(fctx.clone().unwrap(), expr)?)145 Ok(crate::evaluate(fctx.clone().unwrap(), expr)?)146 }146 }147 })147 })148 };148 };crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth142 false,142 false,143 ) {143 ) {144 let fctx = Pending::new();144 let fctx = Pending::new();145 let mut new_bindings = FxHashMap::with_capacity(var.binds_len());145 let mut new_bindings = FxHashMap::with_capacity(into.binds_len());146 let obj = obj.clone();146 let obj = obj.clone();147 let value = Thunk::evaluated(Val::Arr(ArrValue::lazy(vec![147 let value = Thunk::evaluated(Val::Arr(ArrValue::lazy(vec![148 Thunk::evaluated(Val::string(field.clone())),148 Thunk::evaluated(Val::string(field.clone())),149 Thunk!(move || obj.get(field).transpose().expect(149 Thunk!(move || obj.get(field).transpose().expect(150 "field exists, as field name was obtained from object.fields()",150 "field exists, as field name was obtained from object.fields()",151 )),151 )),152 ])));152 ])));153 destruct(var, value, fctx.clone(), &mut new_bindings)?;153 destruct(into, value, fctx.clone(), &mut new_bindings)?;154 let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx);154 let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx);155155156 evaluate_comp(ctx, &specs[1..], callback)?;156 evaluate_comp(ctx, &specs[1..], callback)?;crates/jrsonnet-ir-parser/Cargo.tomldiffbeforeafterboth889[features]9[features]10exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]10exp-null-coaelse = ["jrsonnet-ir/exp-null-coaelse"]11exp-destruct = ["jrsonnet-ir/exp-destruct"]111212[dependencies]13[dependencies]13insta.workspace = true14insta.workspace = truecrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth3use jrsonnet_gcmodule::Acyclic;3use jrsonnet_gcmodule::Acyclic;4use jrsonnet_ir::{4use jrsonnet_ir::{5 unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec,5 unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BinaryOpType, BindSpec, CompSpec,6 Destruct, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse,6 Destruct, DestructRest, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr,7 IfSpecData, ImportKind, IndexPart, LiteralType, Member, ObjBody, ObjComp, ObjMembers, Slice,7 IfElse, IfSpecData, ImportKind, IndexPart, LiteralType, Member, ObjBody, ObjComp, ObjMembers,8 SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility,8 Slice, SliceDesc, Source, Span, Spanned, UnaryOpType, Visibility,9};9};10use jrsonnet_lexer::{collect_lexed_str_block, Lexeme, Lexer, SyntaxKind, T};10use jrsonnet_lexer::{collect_lexed_str_block, Lexeme, Lexer, SyntaxKind, T};1111316}316}317317318fn destruct(p: &mut Parser<'_>) -> R<Destruct> {318fn destruct(p: &mut Parser<'_>) -> R<Destruct> {319 Ok(Destruct::Full(p.expect_ident()?))319 if p.at_ident() {320 return Ok(Destruct::Full(p.expect_ident()?));321 }322 #[cfg(not(feature = "exp-destruct"))]323 return Err(p.error(format!(324 "expected identifier, got {}",325 p.current_desc()326 )));327 #[cfg(feature = "exp-destruct")]328 {329 if p.try_eat(T![?]) {330 return Ok(Destruct::Skip);331 }332 if p.at(T!['[']) {333 return destruct_array(p);334 }335 if p.at(T!['{']) {336 return destruct_object(p);337 }338 Err(p.error(format!(339 "expected destructure pattern, got {}",340 p.current_desc()341 )))342 }320}343}321344345#[cfg(feature = "exp-destruct")]346fn destruct_rest(p: &mut Parser<'_>) -> R<DestructRest> {347 p.eat(T![...])?;348 if p.at_ident() {349 Ok(DestructRest::Keep(p.expect_ident()?))350 } else {351 Ok(DestructRest::Drop)352 }353}354355#[cfg(feature = "exp-destruct")]356fn destruct_array(p: &mut Parser<'_>) -> R<Destruct> {357 p.eat(T!['['])?;358 let mut start = Vec::new();359 let mut rest = None;360 let mut end = Vec::new();361 if !p.at(T![']']) {362 loop {363 if p.at(T![...]) {364 rest = Some(destruct_rest(p)?);365 if p.try_eat(T![,]) {366 if !p.at(T![']']) {367 loop {368 end.push(destruct(p)?);369 if !p.try_eat(T![,]) {370 break;371 }372 if p.at(T![']']) {373 break;374 }375 }376 }377 }378 break;379 }380 start.push(destruct(p)?);381 if !p.try_eat(T![,]) {382 break;383 }384 if p.at(T![']']) {385 break;386 }387 }388 }389 p.eat(T![']'])?;390 Ok(Destruct::Array { start, rest, end })391}392393#[cfg(feature = "exp-destruct")]394fn destruct_object(p: &mut Parser<'_>) -> R<Destruct> {395 p.eat(T!['{'])?;396 let mut fields = Vec::new();397 let mut rest = None;398 if !p.at(T!['}']) {399 loop {400 if p.at(T![...]) {401 rest = Some(destruct_rest(p)?);402 p.try_eat(T![,]);403 break;404 }405 let name = p.expect_ident()?;406 let into = if p.try_eat(T![:]) {407 Some(destruct(p)?)408 } else {409 None410 };411 let default = if p.try_eat(T![=]) {412 Some(Rc::new(spanned(p, expr)?))413 } else {414 None415 };416 fields.push((name, into, default));417 if !p.try_eat(T![,]) {418 break;419 }420 if p.at(T!['}']) {421 break;422 }423 }424 }425 p.eat(T!['}'])?;426 Ok(Destruct::Object { fields, rest })427}428322fn params(p: &mut Parser<'_>) -> R<ExprParams> {429fn params(p: &mut Parser<'_>) -> R<ExprParams> {323 if p.at(T![')']) {430 if p.at(T![')']) {383}490}384491385fn bind(p: &mut Parser<'_>) -> R<BindSpec> {492fn bind(p: &mut Parser<'_>) -> R<BindSpec> {493 #[cfg(feature = "exp-destruct")]494 {495 if !p.at_ident() {496 let d = destruct(p)?;497 p.eat(T![=])?;498 let value = Rc::new(expr(p)?);499 return Ok(BindSpec::Field { into: d, value });500 }501 }386 let name = p.expect_ident()?;502 let name = p.expect_ident()?;387 if p.try_eat(T!['(']) {503 if p.try_eat(T!['(']) {388 let ps = params(p)?;504 let ps = params(p)?;