difftreelog
feat object destructuring defaults
in: master
5 files changed
crates/jrsonnet-evaluator/src/dynamic.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/dynamic.rs
+++ b/crates/jrsonnet-evaluator/src/dynamic.rs
@@ -8,6 +8,9 @@
pub fn new() -> Self {
Self(Cc::new(RefCell::new(None)))
}
+ pub fn new_filled(v: T) -> Self {
+ Self(Cc::new(RefCell::new(Some(v))))
+ }
/// # Panics
/// If wrapper is filled already
pub fn fill(self, value: T) {
crates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
@@ -12,9 +12,11 @@
};
#[allow(clippy::too_many_lines)]
+#[allow(unused_variables)]
pub fn destruct(
d: &Destruct,
parent: Thunk<Val>,
+ fctx: Pending<Context>,
new_bindings: &mut GcHashMap<IStr, Thunk<Val>>,
) -> Result<()> {
match d {
@@ -89,6 +91,7 @@
full: full.clone(),
index: i,
})),
+ fctx.clone(),
new_bindings,
)?;
}
@@ -119,6 +122,7 @@
start: start.len(),
end: end.len(),
})),
+ fctx.clone(),
new_bindings,
)?;
}
@@ -151,6 +155,7 @@
index: i,
end: end.len(),
})),
+ fctx.clone(),
new_bindings,
)?;
}
@@ -189,36 +194,51 @@
Ok(obj)
}
}
- let field_names: Vec<_> = fields.iter().map(|f| f.0.clone()).collect();
+ let field_names: Vec<_> = fields
+ .iter()
+ .filter(|f| f.2.is_none())
+ .map(|f| f.0.clone())
+ .collect();
let full = Thunk::new(tb!(DataThunk {
parent,
field_names: field_names.clone(),
has_rest: rest.is_some()
}));
- for (field, d) in fields {
+ for (field, d, default) in fields {
#[derive(Trace)]
struct FieldThunk {
full: Thunk<ObjValue>,
field: IStr,
+ default: Option<(Pending<Context>, LocExpr)>,
}
impl ThunkValue for FieldThunk {
type Output = Val;
fn get(self: Box<Self>, s: State) -> Result<Self::Output> {
let full = self.full.evaluate(s.clone())?;
- let field = full.get(s, self.field)?.expect("shape is checked");
- Ok(field)
+ if let Some(field) = full.get(s.clone(), self.field)? {
+ Ok(field)
+ } else {
+ let (fctx, expr) = self.default.as_ref().expect("shape is checked");
+ Ok(evaluate(s, fctx.clone().unwrap(), &expr)?)
+ }
}
}
let value = Thunk::new(tb!(FieldThunk {
full: full.clone(),
- field: field.clone()
+ field: field.clone(),
+ default: default.clone().map(|e| (fctx.clone(), e)),
}));
if let Some(d) = d {
- destruct(d, value, new_bindings)?;
+ destruct(d, value, fctx.clone(), new_bindings)?;
} else {
- destruct(&Destruct::Full(field.clone()), value, new_bindings)?;
+ destruct(
+ &Destruct::Full(field.clone()),
+ value,
+ fctx.clone(),
+ new_bindings,
+ )?;
}
}
}
@@ -251,10 +271,10 @@
}
let data = Thunk::new(tb!(EvaluateThunkValue {
name: into.name(),
- fctx,
+ fctx: fctx.clone(),
expr: value.clone(),
}));
- destruct(into, data, new_bindings)?;
+ destruct(into, data, fctx, new_bindings)?;
}
BindSpec::Function {
name,
crates/jrsonnet-evaluator/src/function/parse.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/function/parse.rs
+++ b/crates/jrsonnet-evaluator/src/function/parse.rs
@@ -56,7 +56,12 @@
args.unnamed_iter(s.clone(), ctx.clone(), tailstrict, &mut |id, arg| {
let name = params[id].0.clone();
- destruct(&name, arg, &mut passed_args)?;
+ destruct(
+ &name,
+ arg,
+ Pending::new_filled(ctx.clone()),
+ &mut passed_args,
+ )?;
filled_positionals += 1;
Ok(())
})?;
@@ -96,6 +101,7 @@
name: param.0.name().unwrap_or_else(|| "<destruct>".into()),
value: param.1.clone().expect("default exists"),
})),
+ fctx.clone(),
&mut defaults,
)?;
if param.0.name().is_some() {
@@ -230,6 +236,7 @@
name: param.0.name().unwrap_or_else(|| "<destruct>".into()),
value: v.clone(),
})),
+ fctx.clone(),
&mut bindings,
)?;
} else {
@@ -238,6 +245,7 @@
Thunk::new(tb!(DependsOnUnbound(
param.0.name().unwrap_or_else(|| "<destruct>".into())
))),
+ fctx.clone(),
&mut bindings,
)?;
}
crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};1112use crate::source::Source;1314#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]15#[derive(Debug, PartialEq, Trace)]16pub enum FieldName {17 /// {fixed: 2}18 Fixed(IStr),19 /// {["dyn"+"amic"]: 3}20 Dyn(LocExpr),21}2223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]24#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]25pub enum Visibility {26 /// :27 Normal,28 /// ::29 Hidden,30 /// :::31 Unhide,32}3334impl Visibility {35 pub fn is_visible(&self) -> bool {36 matches!(self, Self::Normal | Self::Unhide)37 }38}3940#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]41#[derive(Clone, Debug, PartialEq, Trace)]42pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]45#[derive(Debug, PartialEq, Trace)]46pub struct FieldMember {47 pub name: FieldName,48 pub plus: bool,49 pub params: Option<ParamsDesc>,50 pub visibility: Visibility,51 pub value: LocExpr,52}5354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]55#[derive(Debug, PartialEq, Trace)]56pub enum Member {57 Field(FieldMember),58 BindStmt(BindSpec),59 AssertStmt(AssertStmt),60}6162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]63#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]64pub enum UnaryOpType {65 Plus,66 Minus,67 BitNot,68 Not,69}7071impl Display for UnaryOpType {72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {73 use UnaryOpType::*;74 write!(75 f,76 "{}",77 match self {78 Plus => "+",79 Minus => "-",80 BitNot => "~",81 Not => "!",82 }83 )84 }85}8687#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]88#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]89pub enum BinaryOpType {90 Mul,91 Div,9293 /// Implemented as intrinsic, put here for completeness94 Mod,9596 Add,97 Sub,9899 Lhs,100 Rhs,101102 Lt,103 Gt,104 Lte,105 Gte,106107 BitAnd,108 BitOr,109 BitXor,110111 Eq,112 Neq,113114 And,115 Or,116117 // Equialent to std.objectHasEx(a, b, true)118 In,119}120121impl Display for BinaryOpType {122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {123 use BinaryOpType::*;124 write!(125 f,126 "{}",127 match self {128 Mul => "*",129 Div => "/",130 Mod => "%",131 Add => "+",132 Sub => "-",133 Lhs => "<<",134 Rhs => ">>",135 Lt => "<",136 Gt => ">",137 Lte => "<=",138 Gte => ">=",139 BitAnd => "&",140 BitOr => "|",141 BitXor => "^",142 Eq => "==",143 Neq => "!=",144 And => "&&",145 Or => "||",146 In => "in",147 }148 )149 }150}151152/// name, default value153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]154#[derive(Debug, PartialEq, Trace)]155pub struct Param(pub Destruct, pub Option<LocExpr>);156157/// Defined function parameters158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]159#[derive(Debug, Clone, PartialEq, Trace)]160pub struct ParamsDesc(pub Rc<Vec<Param>>);161162impl Deref for ParamsDesc {163 type Target = Vec<Param>;164 fn deref(&self) -> &Self::Target {165 &self.0166 }167}168169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, PartialEq, Trace)]171pub struct ArgsDesc {172 pub unnamed: Vec<LocExpr>,173 pub named: Vec<(IStr, LocExpr)>,174}175impl ArgsDesc {176 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {177 Self { unnamed, named }178 }179}180181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, Clone, PartialEq, Eq, Trace)]183pub enum DestructRest {184 /// ...rest185 Keep(IStr),186 /// ...187 Drop,188}189190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]191#[derive(Debug, Clone, PartialEq, Eq, Trace)]192pub enum Destruct {193 Full(IStr),194 #[cfg(feature = "exp-destruct")]195 Skip,196 #[cfg(feature = "exp-destruct")]197 Array {198 start: Vec<Destruct>,199 rest: Option<DestructRest>,200 end: Vec<Destruct>,201 },202 #[cfg(feature = "exp-destruct")]203 Object {204 fields: Vec<(IStr, Option<Destruct>)>,205 rest: Option<DestructRest>,206 },207}208impl Destruct {209 /// Name of destructure, used for function parameter names210 pub fn name(&self) -> Option<IStr> {211 match self {212 Self::Full(name) => Some(name.clone()),213 #[cfg(feature = "exp-destruct")]214 _ => None,215 }216 }217}218219#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]220#[derive(Debug, Clone, PartialEq, Trace)]221pub enum BindSpec {222 Field {223 into: Destruct,224 value: LocExpr,225 },226 Function {227 name: IStr,228 params: ParamsDesc,229 value: LocExpr,230 },231}232233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]234#[derive(Debug, PartialEq, Trace)]235pub struct IfSpecData(pub LocExpr);236237#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]238#[derive(Debug, PartialEq, Trace)]239pub struct ForSpecData(pub IStr, pub LocExpr);240241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]242#[derive(Debug, PartialEq, Trace)]243pub enum CompSpec {244 IfSpec(IfSpecData),245 ForSpec(ForSpecData),246}247248#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]249#[derive(Debug, PartialEq, Trace)]250pub struct ObjComp {251 pub pre_locals: Vec<BindSpec>,252 pub key: LocExpr,253 pub plus: bool,254 pub value: LocExpr,255 pub post_locals: Vec<BindSpec>,256 pub compspecs: Vec<CompSpec>,257}258259#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]260#[derive(Debug, PartialEq, Trace)]261pub enum ObjBody {262 MemberList(Vec<Member>),263 ObjComp(ObjComp),264}265266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]267#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]268pub enum LiteralType {269 This,270 Super,271 Dollar,272 Null,273 True,274 False,275}276277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]278#[derive(Debug, PartialEq, Trace)]279pub struct SliceDesc {280 pub start: Option<LocExpr>,281 pub end: Option<LocExpr>,282 pub step: Option<LocExpr>,283}284285/// Syntax base286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]287#[derive(Debug, PartialEq, Trace)]288pub enum Expr {289 Literal(LiteralType),290291 /// String value: "hello"292 Str(IStr),293 /// Number: 1, 2.0, 2e+20294 Num(f64),295 /// Variable name: test296 Var(IStr),297298 /// Array of expressions: [1, 2, "Hello"]299 Arr(Vec<LocExpr>),300 /// Array comprehension:301 /// ```jsonnet302 /// ingredients: [303 /// { kind: kind, qty: 4 / 3 }304 /// for kind in [305 /// 'Honey Syrup',306 /// 'Lemon Juice',307 /// 'Farmers Gin',308 /// ]309 /// ],310 /// ```311 ArrComp(LocExpr, Vec<CompSpec>),312313 /// Object: {a: 2}314 Obj(ObjBody),315 /// Object extension: var1 {b: 2}316 ObjExtend(LocExpr, ObjBody),317318 /// (obj)319 Parened(LocExpr),320321 /// -2322 UnaryOp(UnaryOpType, LocExpr),323 /// 2 - 2324 BinaryOp(LocExpr, BinaryOpType, LocExpr),325 /// assert 2 == 2 : "Math is broken"326 AssertExpr(AssertStmt, LocExpr),327 /// local a = 2; { b: a }328 LocalExpr(Vec<BindSpec>, LocExpr),329330 /// import "hello"331 Import(IStr),332 /// importStr "file.txt"333 ImportStr(IStr),334 /// importBin "file.txt"335 ImportBin(IStr),336 /// error "I'm broken"337 ErrorStmt(LocExpr),338 /// a(b, c)339 Apply(LocExpr, ArgsDesc, bool),340 /// a[b]341 Index(LocExpr, LocExpr),342 /// function(x) x343 Function(ParamsDesc, LocExpr),344 /// std.thisFile345 IntrinsicThisFile,346 /// std.id,347 IntrinsicId,348 /// std.primitiveEquals349 Intrinsic(IStr),350 /// if true == false then 1 else 2351 IfElse {352 cond: IfSpecData,353 cond_then: LocExpr,354 cond_else: Option<LocExpr>,355 },356 Slice(LocExpr, SliceDesc),357}358359/// file, begin offset, end offset360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]361#[derive(Clone, PartialEq, Eq, Trace)]362#[skip_trace]363#[repr(C)]364pub struct ExprLocation(pub Source, pub u32, pub u32);365impl ExprLocation {366 pub fn belongs_to(&self, other: &ExprLocation) -> bool {367 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2368 }369}370371#[cfg(target_pointer_width = "64")]372static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);373374impl Debug for ExprLocation {375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {376 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)377 }378}379380/// Holds AST expression and its location in source file381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]382#[derive(Clone, PartialEq, Trace)]383pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);384385#[cfg(target_pointer_width = "64")]386static_assertions::assert_eq_size!(LocExpr, [u8; 24]);387388impl Debug for LocExpr {389 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {390 if f.alternate() {391 write!(f, "{:#?}", self.0)?;392 } else {393 write!(f, "{:?}", self.0)?;394 }395 write!(f, " from {:?}", self.1)?;396 Ok(())397 }398}1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};1112use crate::source::Source;1314#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]15#[derive(Debug, PartialEq, Trace)]16pub enum FieldName {17 /// {fixed: 2}18 Fixed(IStr),19 /// {["dyn"+"amic"]: 3}20 Dyn(LocExpr),21}2223#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]24#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]25pub enum Visibility {26 /// :27 Normal,28 /// ::29 Hidden,30 /// :::31 Unhide,32}3334impl Visibility {35 pub fn is_visible(&self) -> bool {36 matches!(self, Self::Normal | Self::Unhide)37 }38}3940#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]41#[derive(Clone, Debug, PartialEq, Trace)]42pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4344#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]45#[derive(Debug, PartialEq, Trace)]46pub struct FieldMember {47 pub name: FieldName,48 pub plus: bool,49 pub params: Option<ParamsDesc>,50 pub visibility: Visibility,51 pub value: LocExpr,52}5354#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]55#[derive(Debug, PartialEq, Trace)]56pub enum Member {57 Field(FieldMember),58 BindStmt(BindSpec),59 AssertStmt(AssertStmt),60}6162#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]63#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]64pub enum UnaryOpType {65 Plus,66 Minus,67 BitNot,68 Not,69}7071impl Display for UnaryOpType {72 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {73 use UnaryOpType::*;74 write!(75 f,76 "{}",77 match self {78 Plus => "+",79 Minus => "-",80 BitNot => "~",81 Not => "!",82 }83 )84 }85}8687#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]88#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]89pub enum BinaryOpType {90 Mul,91 Div,9293 /// Implemented as intrinsic, put here for completeness94 Mod,9596 Add,97 Sub,9899 Lhs,100 Rhs,101102 Lt,103 Gt,104 Lte,105 Gte,106107 BitAnd,108 BitOr,109 BitXor,110111 Eq,112 Neq,113114 And,115 Or,116117 // Equialent to std.objectHasEx(a, b, true)118 In,119}120121impl Display for BinaryOpType {122 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {123 use BinaryOpType::*;124 write!(125 f,126 "{}",127 match self {128 Mul => "*",129 Div => "/",130 Mod => "%",131 Add => "+",132 Sub => "-",133 Lhs => "<<",134 Rhs => ">>",135 Lt => "<",136 Gt => ">",137 Lte => "<=",138 Gte => ">=",139 BitAnd => "&",140 BitOr => "|",141 BitXor => "^",142 Eq => "==",143 Neq => "!=",144 And => "&&",145 Or => "||",146 In => "in",147 }148 )149 }150}151152/// name, default value153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]154#[derive(Debug, PartialEq, Trace)]155pub struct Param(pub Destruct, pub Option<LocExpr>);156157/// Defined function parameters158#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]159#[derive(Debug, Clone, PartialEq, Trace)]160pub struct ParamsDesc(pub Rc<Vec<Param>>);161162impl Deref for ParamsDesc {163 type Target = Vec<Param>;164 fn deref(&self) -> &Self::Target {165 &self.0166 }167}168169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, PartialEq, Trace)]171pub struct ArgsDesc {172 pub unnamed: Vec<LocExpr>,173 pub named: Vec<(IStr, LocExpr)>,174}175impl ArgsDesc {176 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {177 Self { unnamed, named }178 }179}180181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, Clone, PartialEq, Eq, Trace)]183pub enum DestructRest {184 /// ...rest185 Keep(IStr),186 /// ...187 Drop,188}189190#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]191#[derive(Debug, Clone, PartialEq, Trace)]192pub enum Destruct {193 Full(IStr),194 #[cfg(feature = "exp-destruct")]195 Skip,196 #[cfg(feature = "exp-destruct")]197 Array {198 start: Vec<Destruct>,199 rest: Option<DestructRest>,200 end: Vec<Destruct>,201 },202 #[cfg(feature = "exp-destruct")]203 Object {204 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,205 rest: Option<DestructRest>,206 },207}208impl Destruct {209 /// Name of destructure, used for function parameter names210 pub fn name(&self) -> Option<IStr> {211 match self {212 Self::Full(name) => Some(name.clone()),213 #[cfg(feature = "exp-destruct")]214 _ => None,215 }216 }217}218219#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]220#[derive(Debug, Clone, PartialEq, Trace)]221pub enum BindSpec {222 Field {223 into: Destruct,224 value: LocExpr,225 },226 Function {227 name: IStr,228 params: ParamsDesc,229 value: LocExpr,230 },231}232233#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]234#[derive(Debug, PartialEq, Trace)]235pub struct IfSpecData(pub LocExpr);236237#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]238#[derive(Debug, PartialEq, Trace)]239pub struct ForSpecData(pub IStr, pub LocExpr);240241#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]242#[derive(Debug, PartialEq, Trace)]243pub enum CompSpec {244 IfSpec(IfSpecData),245 ForSpec(ForSpecData),246}247248#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]249#[derive(Debug, PartialEq, Trace)]250pub struct ObjComp {251 pub pre_locals: Vec<BindSpec>,252 pub key: LocExpr,253 pub plus: bool,254 pub value: LocExpr,255 pub post_locals: Vec<BindSpec>,256 pub compspecs: Vec<CompSpec>,257}258259#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]260#[derive(Debug, PartialEq, Trace)]261pub enum ObjBody {262 MemberList(Vec<Member>),263 ObjComp(ObjComp),264}265266#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]267#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]268pub enum LiteralType {269 This,270 Super,271 Dollar,272 Null,273 True,274 False,275}276277#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]278#[derive(Debug, PartialEq, Trace)]279pub struct SliceDesc {280 pub start: Option<LocExpr>,281 pub end: Option<LocExpr>,282 pub step: Option<LocExpr>,283}284285/// Syntax base286#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]287#[derive(Debug, PartialEq, Trace)]288pub enum Expr {289 Literal(LiteralType),290291 /// String value: "hello"292 Str(IStr),293 /// Number: 1, 2.0, 2e+20294 Num(f64),295 /// Variable name: test296 Var(IStr),297298 /// Array of expressions: [1, 2, "Hello"]299 Arr(Vec<LocExpr>),300 /// Array comprehension:301 /// ```jsonnet302 /// ingredients: [303 /// { kind: kind, qty: 4 / 3 }304 /// for kind in [305 /// 'Honey Syrup',306 /// 'Lemon Juice',307 /// 'Farmers Gin',308 /// ]309 /// ],310 /// ```311 ArrComp(LocExpr, Vec<CompSpec>),312313 /// Object: {a: 2}314 Obj(ObjBody),315 /// Object extension: var1 {b: 2}316 ObjExtend(LocExpr, ObjBody),317318 /// (obj)319 Parened(LocExpr),320321 /// -2322 UnaryOp(UnaryOpType, LocExpr),323 /// 2 - 2324 BinaryOp(LocExpr, BinaryOpType, LocExpr),325 /// assert 2 == 2 : "Math is broken"326 AssertExpr(AssertStmt, LocExpr),327 /// local a = 2; { b: a }328 LocalExpr(Vec<BindSpec>, LocExpr),329330 /// import "hello"331 Import(IStr),332 /// importStr "file.txt"333 ImportStr(IStr),334 /// importBin "file.txt"335 ImportBin(IStr),336 /// error "I'm broken"337 ErrorStmt(LocExpr),338 /// a(b, c)339 Apply(LocExpr, ArgsDesc, bool),340 /// a[b]341 Index(LocExpr, LocExpr),342 /// function(x) x343 Function(ParamsDesc, LocExpr),344 /// std.thisFile345 IntrinsicThisFile,346 /// std.id,347 IntrinsicId,348 /// std.primitiveEquals349 Intrinsic(IStr),350 /// if true == false then 1 else 2351 IfElse {352 cond: IfSpecData,353 cond_then: LocExpr,354 cond_else: Option<LocExpr>,355 },356 Slice(LocExpr, SliceDesc),357}358359/// file, begin offset, end offset360#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]361#[derive(Clone, PartialEq, Eq, Trace)]362#[skip_trace]363#[repr(C)]364pub struct ExprLocation(pub Source, pub u32, pub u32);365impl ExprLocation {366 pub fn belongs_to(&self, other: &ExprLocation) -> bool {367 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2368 }369}370371#[cfg(target_pointer_width = "64")]372static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);373374impl Debug for ExprLocation {375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {376 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)377 }378}379380/// Holds AST expression and its location in source file381#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]382#[derive(Clone, PartialEq, Trace)]383pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);384385#[cfg(target_pointer_width = "64")]386static_assertions::assert_eq_size!(LocExpr, [u8; 24]);387388impl Debug for LocExpr {389 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {390 if f.alternate() {391 write!(f, "{:#?}", self.0)?;392 } else {393 write!(f, "{:?}", self.0)?;394 }395 write!(f, " from {:?}", self.1)?;396 Ok(())397 }398}crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::redundant_closure_call)]
+#![allow(clippy::redundant_closure_call, clippy::derive_partial_eq_without_eq)]
use std::rc::Rc;
@@ -109,7 +109,7 @@
}
pub rule destruct_object(s: &ParserSettings) -> expr::Destruct
= "{" _
- fields:(name:id() _ into:(":" _ into:destruct(s) {into})? {(name, into)})**comma()
+ fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default)})**comma()
rest:(
comma() rest:destruct_rest()? {rest}
/ comma()? {None}