difftreelog
feat sync jsonnet stdlib changes
in: master
8 files changed
crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/manifest.rs
@@ -413,18 +413,19 @@
val.value_type()
)
};
- if !arr.is_empty() {
- for (i, v) in arr.iter().enumerate() {
- let v = v.with_description(|| format!("elem <{i}> evaluation"))?;
- out.push_str("---\n");
- in_description_frame(
- || format!("elem <{i}> manifestification"),
- || self.inner.manifest_buf(v, out),
- )?;
+ for (i, v) in arr.iter().enumerate() {
+ if i != 0 {
out.push('\n');
}
+ let v = v.with_description(|| format!("elem <{i}> evaluation"))?;
+ out.push_str("---\n");
+ in_description_frame(
+ || format!("elem <{i}> manifestification"),
+ || self.inner.manifest_buf(v, out),
+ )?;
}
if self.c_document_end {
+ out.push('\n');
out.push_str("...");
}
if self.end_newline {
crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -237,7 +237,11 @@
Expr::ArrComp(expr, specs)
}
pub rule number_expr(s: &ParserSettings) -> Expr
- = n:number() { expr::Expr::Num(n) }
+ = n:number() {? if n.is_finite() {
+ Ok(expr::Expr::Num(n))
+ } else {
+ Err("!!!numbers are finite")
+ }}
pub rule var_expr(s: &ParserSettings) -> Expr
= n:id() { expr::Expr::Var(n) }
pub rule id_loc(s: &ParserSettings) -> LocExpr
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -3,6 +3,7 @@
use std::{
cell::{Ref, RefCell, RefMut},
collections::HashMap,
+ f64,
rc::Rc,
};
@@ -14,6 +15,7 @@
error::{ErrorKind::*, Result},
function::{CallLocation, FuncVal, TlaArg},
trace::PathResolver,
+ val::NumValue,
ContextBuilder, IStr, ObjValue, ObjValueBuilder, Thunk, Val,
};
use jrsonnet_gcmodule::{Acyclic, Cc, Trace};
@@ -63,6 +65,7 @@
("isObject", builtin_is_object::INST),
("isArray", builtin_is_array::INST),
("isFunction", builtin_is_function::INST),
+ ("isNull", builtin_is_null::INST),
// Arrays
("makeArray", builtin_make_array::INST),
("repeat", builtin_repeat::INST),
@@ -104,6 +107,8 @@
("floor", builtin_floor::INST),
("ceil", builtin_ceil::INST),
("log", builtin_log::INST),
+ ("log2", builtin_log2::INST),
+ ("log10", builtin_log10::INST),
("pow", builtin_pow::INST),
("sqrt", builtin_sqrt::INST),
("sin", builtin_sin::INST),
@@ -121,6 +126,9 @@
("isOdd", builtin_is_odd::INST),
("isInteger", builtin_is_integer::INST),
("isDecimal", builtin_is_decimal::INST),
+ ("deg2rad", builtin_deg2rad::INST),
+ ("rad2deg", builtin_rad2deg::INST),
+ ("hypot", builtin_hypot::INST),
// Operator
("mod", builtin_mod::INST),
("primitiveEquals", builtin_primitive_equals::INST),
@@ -201,6 +209,7 @@
("lstripChars", builtin_lstrip_chars::INST),
("rstripChars", builtin_rstrip_chars::INST),
("stripChars", builtin_strip_chars::INST),
+ ("trim", builtin_trim::INST),
// Misc
("length", builtin_length::INST),
("get", builtin_get::INST),
@@ -248,6 +257,10 @@
builder.method("trace", builtin_trace { settings });
builder.method("id", FuncVal::Id);
+ builder.field("pi").hide().value(Val::Num(
+ NumValue::new(f64::consts::PI).expect("pi is finite"),
+ ));
+
#[cfg(feature = "exp-regex")]
{
// Regex
crates/jrsonnet-stdlib/src/math.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/math.rs
+++ b/crates/jrsonnet-stdlib/src/math.rs
@@ -1,3 +1,5 @@
+use std::f64;
+
use jrsonnet_evaluator::{function::builtin, typed::PositiveF64};
#[builtin]
@@ -56,6 +58,16 @@
}
#[builtin]
+pub fn builtin_log2(x: f64) -> f64 {
+ x.log2()
+}
+
+#[builtin]
+pub fn builtin_log10(x: f64) -> f64 {
+ x.log10()
+}
+
+#[builtin]
pub fn builtin_pow(x: f64, n: f64) -> f64 {
x.powf(n)
}
@@ -153,3 +165,18 @@
pub fn builtin_is_decimal(x: f64) -> bool {
builtin_round(x) != x
}
+
+#[builtin]
+pub fn builtin_deg2rad(x: f64) -> f64 {
+ x * f64::consts::PI / 180.0
+}
+
+#[builtin]
+pub fn builtin_rad2deg(x: f64) -> f64 {
+ x * 180.0 / f64::consts::PI
+}
+
+#[builtin]
+pub fn builtin_hypot(x: f64, y: f64) -> f64 {
+ x.hypot(y)
+}
crates/jrsonnet-stdlib/src/misc.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/misc.rs
+++ b/crates/jrsonnet-stdlib/src/misc.rs
@@ -156,8 +156,16 @@
#[cfg(feature = "exp-preserve-order")]
true,
);
- let a = a.manifest(&format).description("<a> manifestification")?;
- let b = b.manifest(&format).description("<b> manifestification")?;
+ let a = if let Some(a) = a.as_str() {
+ format!("<A>\n{a}\n</A>")
+ } else {
+ a.manifest(&format).description("<a> manifestification")?
+ };
+ let b = if let Some(b) = b.as_str() {
+ format!("<B>\n{b}\n</B>")
+ } else {
+ b.manifest(&format).description("<b> manifestification")?
+ };
bail!("assertion failed: A != B\nA: {a}\nB: {b}")
}
@@ -166,9 +174,7 @@
let Some(patch) = patch.as_obj() else {
return Ok(patch);
};
- let Some(target) = target.as_obj() else {
- return Ok(Val::Obj(patch));
- };
+ let target = target.as_obj().unwrap_or_else(|| ObjValue::new_empty());
let target_fields = target
.fields(
// FIXME: Makes no sense to preserve order for BTreeSet, it would be better to use IndexSet here?
@@ -203,10 +209,7 @@
if matches!(field_patch, Val::Null) {
continue;
}
- let Some(field_target) = target.get(field.clone())? else {
- out.field(field.clone()).value(field_patch);
- continue;
- };
+ let field_target = target.get(field.clone())?.unwrap_or(Val::Null);
out.field(field.clone())
.value(builtin_merge_patch(field_target, field_patch)?);
}
crates/jrsonnet-stdlib/src/objects.rsdiffbeforeafterboth1use jrsonnet_evaluator::{2 function::builtin,3 val::{ArrValue, Val},4 IStr, ObjValue, ObjValueBuilder,5};67#[builtin]8pub fn builtin_object_fields_ex(9 obj: ObjValue,10 hidden: bool,1112 #[default(false)]13 #[cfg(feature = "exp-preserve-order")]14 preserve_order: bool,15) -> Vec<Val> {16 let out = obj.fields_ex(17 hidden,18 #[cfg(feature = "exp-preserve-order")]19 preserve_order,20 );21 out.into_iter().map(Val::string).collect::<Vec<_>>()22}2324#[builtin]25pub fn builtin_object_fields(26 o: ObjValue,2728 #[default(false)]29 #[cfg(feature = "exp-preserve-order")]30 preserve_order: bool,31) -> Vec<Val> {32 builtin_object_fields_ex(33 o,34 false,35 #[cfg(feature = "exp-preserve-order")]36 preserve_order,37 )38}3940#[builtin]41pub fn builtin_object_fields_all(42 o: ObjValue,4344 #[default(false)]45 #[cfg(feature = "exp-preserve-order")]46 preserve_order: bool,47) -> Vec<Val> {48 builtin_object_fields_ex(49 o,50 true,51 #[cfg(feature = "exp-preserve-order")]52 preserve_order,53 )54}5556pub fn builtin_object_values_ex(57 o: ObjValue,58 include_hidden: bool,5960 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,61) -> ArrValue {62 o.values_ex(63 include_hidden,64 #[cfg(feature = "exp-preserve-order")]65 preserve_order,66 )67}68#[builtin]69pub fn builtin_object_values(70 o: ObjValue,7172 #[default(false)]73 #[cfg(feature = "exp-preserve-order")]74 preserve_order: bool,75) -> ArrValue {76 builtin_object_values_ex(77 o,78 false,79 #[cfg(feature = "exp-preserve-order")]80 preserve_order,81 )82}83#[builtin]84pub fn builtin_object_values_all(85 o: ObjValue,8687 #[default(false)]88 #[cfg(feature = "exp-preserve-order")]89 preserve_order: bool,90) -> ArrValue {91 builtin_object_values_ex(92 o,93 true,94 #[cfg(feature = "exp-preserve-order")]95 preserve_order,96 )97}9899pub fn builtin_object_keys_values_ex(100 o: ObjValue,101 include_hidden: bool,102103 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,104) -> ArrValue {105 o.key_values_ex(106 include_hidden,107 #[cfg(feature = "exp-preserve-order")]108 preserve_order,109 )110}111#[builtin]112pub fn builtin_object_keys_values(113 o: ObjValue,114115 #[default(false)]116 #[cfg(feature = "exp-preserve-order")]117 preserve_order: bool,118) -> ArrValue {119 builtin_object_keys_values_ex(120 o,121 false,122 #[cfg(feature = "exp-preserve-order")]123 preserve_order,124 )125}126#[builtin]127pub fn builtin_object_keys_values_all(128 o: ObjValue,129130 #[default(false)]131 #[cfg(feature = "exp-preserve-order")]132 preserve_order: bool,133) -> ArrValue {134 builtin_object_keys_values_ex(135 o,136 true,137 #[cfg(feature = "exp-preserve-order")]138 preserve_order,139 )140}141142#[builtin]143pub fn builtin_object_has_ex(obj: ObjValue, fname: IStr, hidden: bool) -> bool {144 obj.has_field_ex(fname, hidden)145}146147#[builtin]148pub fn builtin_object_has(o: ObjValue, f: IStr) -> bool {149 o.has_field(f)150}151152#[builtin]153pub fn builtin_object_has_all(o: ObjValue, f: IStr) -> bool {154 o.has_field_include_hidden(f)155}156157#[builtin]158pub fn builtin_object_remove_key(159 obj: ObjValue,160 key: IStr,161162 // Standard implementation uses std.objectFields without such argument, we can't163 // assume order preservation should always be enabled/disabled164 #[default(false)]165 #[cfg(feature = "exp-preserve-order")]166 preserve_order: bool,167) -> ObjValue {168 let mut new_obj = ObjValueBuilder::with_capacity(obj.len() - 1);169 for (k, v) in obj.iter(170 #[cfg(feature = "exp-preserve-order")]171 preserve_order,172 ) {173 if k == key {174 continue;175 }176 new_obj.field(k).value(v.unwrap());177 }178179 new_obj.build()180}1use jrsonnet_evaluator::{2 function::builtin,3 rustc_hash::FxHashSet,4 val::{ArrValue, Val},5 IStr, MaybeUnbound, ObjValue, ObjValueBuilder, Thunk,6};78#[builtin]9pub fn builtin_object_fields_ex(10 obj: ObjValue,11 hidden: bool,1213 #[default(false)]14 #[cfg(feature = "exp-preserve-order")]15 preserve_order: bool,16) -> Vec<Val> {17 let out = obj.fields_ex(18 hidden,19 #[cfg(feature = "exp-preserve-order")]20 preserve_order,21 );22 out.into_iter().map(Val::string).collect::<Vec<_>>()23}2425#[builtin]26pub fn builtin_object_fields(27 o: ObjValue,2829 #[default(false)]30 #[cfg(feature = "exp-preserve-order")]31 preserve_order: bool,32) -> Vec<Val> {33 builtin_object_fields_ex(34 o,35 false,36 #[cfg(feature = "exp-preserve-order")]37 preserve_order,38 )39}4041#[builtin]42pub fn builtin_object_fields_all(43 o: ObjValue,4445 #[default(false)]46 #[cfg(feature = "exp-preserve-order")]47 preserve_order: bool,48) -> Vec<Val> {49 builtin_object_fields_ex(50 o,51 true,52 #[cfg(feature = "exp-preserve-order")]53 preserve_order,54 )55}5657pub fn builtin_object_values_ex(58 o: ObjValue,59 include_hidden: bool,6061 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,62) -> ArrValue {63 o.values_ex(64 include_hidden,65 #[cfg(feature = "exp-preserve-order")]66 preserve_order,67 )68}69#[builtin]70pub fn builtin_object_values(71 o: ObjValue,7273 #[default(false)]74 #[cfg(feature = "exp-preserve-order")]75 preserve_order: bool,76) -> ArrValue {77 builtin_object_values_ex(78 o,79 false,80 #[cfg(feature = "exp-preserve-order")]81 preserve_order,82 )83}84#[builtin]85pub fn builtin_object_values_all(86 o: ObjValue,8788 #[default(false)]89 #[cfg(feature = "exp-preserve-order")]90 preserve_order: bool,91) -> ArrValue {92 builtin_object_values_ex(93 o,94 true,95 #[cfg(feature = "exp-preserve-order")]96 preserve_order,97 )98}99100pub fn builtin_object_keys_values_ex(101 o: ObjValue,102 include_hidden: bool,103104 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,105) -> ArrValue {106 o.key_values_ex(107 include_hidden,108 #[cfg(feature = "exp-preserve-order")]109 preserve_order,110 )111}112#[builtin]113pub fn builtin_object_keys_values(114 o: ObjValue,115116 #[default(false)]117 #[cfg(feature = "exp-preserve-order")]118 preserve_order: bool,119) -> ArrValue {120 builtin_object_keys_values_ex(121 o,122 false,123 #[cfg(feature = "exp-preserve-order")]124 preserve_order,125 )126}127#[builtin]128pub fn builtin_object_keys_values_all(129 o: ObjValue,130131 #[default(false)]132 #[cfg(feature = "exp-preserve-order")]133 preserve_order: bool,134) -> ArrValue {135 builtin_object_keys_values_ex(136 o,137 true,138 #[cfg(feature = "exp-preserve-order")]139 preserve_order,140 )141}142143#[builtin]144pub fn builtin_object_has_ex(obj: ObjValue, fname: IStr, hidden: bool) -> bool {145 obj.has_field_ex(fname, hidden)146}147148#[builtin]149pub fn builtin_object_has(o: ObjValue, f: IStr) -> bool {150 o.has_field(f)151}152153#[builtin]154pub fn builtin_object_has_all(o: ObjValue, f: IStr) -> bool {155 o.has_field_include_hidden(f)156}157158#[builtin]159pub fn builtin_object_remove_key(160 obj: ObjValue,161 key: IStr,162163 // Standard implementation uses std.objectFields without such argument, we can't164 // assume order preservation should always be enabled/disabled165 #[default(false)]166 #[cfg(feature = "exp-preserve-order")]167 preserve_order: bool,168) -> ObjValue {169 let mut new_obj = ObjValueBuilder::with_capacity(obj.len() - 1);170 let all_fields = obj.fields_ex(171 true,172 #[cfg(feature = "exp-preserve-order")]173 preserve_order,174 );175 let visible_fields = obj176 .fields_ex(177 false,178 #[cfg(feature = "exp-preserve-order")]179 preserve_order,180 )181 .into_iter()182 .collect::<FxHashSet<_>>();183184 for field in &all_fields {185 if *field == key {186 continue;187 }188 let mut b = new_obj.field(field.clone());189 if !visible_fields.contains(&field) {190 b = b.hide();191 }192 let _ = b.binding(MaybeUnbound::Bound(Thunk::result(193 obj.get(field.clone()).transpose().expect("field exists"),194 )));195 }196197 new_obj.build()198}crates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/strings.rs
+++ b/crates/jrsonnet-stdlib/src/strings.rs
@@ -254,6 +254,19 @@
Ok(str.as_str().trim_matches(pattern).into())
}
+#[builtin]
+pub fn builtin_trim(str: IStr) -> String {
+ let filter =
+ |v: char| {
+ v == ' '
+ || v == '\t' || v == '\n'
+ || v == '\u{000c}'
+ || v == '\r' || v == '\u{0085}'
+ || v == '\u{00a0}'
+ };
+ str.as_str().trim_matches(filter).to_string()
+}
+
fn new_trim_pattern(chars: IndexableVal) -> Result<impl Fn(char) -> bool> {
let chars: BTreeSet<char> = match chars {
IndexableVal::Str(chars) => chars.chars().collect(),
crates/jrsonnet-stdlib/src/types.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/types.rs
+++ b/crates/jrsonnet-stdlib/src/types.rs
@@ -29,3 +29,7 @@
pub fn builtin_is_function(v: Val) -> bool {
matches!(v, Val::Func(_))
}
+#[builtin]
+pub fn builtin_is_null(v: Val) -> bool {
+ matches!(v, Val::Null)
+}