difftreelog
fix(types) use absolute paths in macro
in: master
2 files changed
crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth1use crate::{2 equals,3 error::{Error::*, Result},4 evaluate, parse_args, primitive_equals, push, throw,5 typed::CheckType,6 with_state, ArrValue, Context, FuncVal, LazyVal, Val,7};8use format::{format_arr, format_obj};9use jrsonnet_parser::{ArgsDesc, BinaryOpType, ExprLocation};10use jrsonnet_types::{ty, ComplexValType, ValType};11use std::{collections::HashMap, path::PathBuf, rc::Rc};1213pub mod stdlib;14pub use stdlib::*;1516use self::manifest::{escape_string_json, manifest_json_ex, ManifestJsonOptions, ManifestType};1718pub mod format;19pub mod manifest;20pub mod sort;2122fn std_format(str: Rc<str>, vals: Val) -> Result<Val> {23 push(24 &Some(ExprLocation(Rc::from(PathBuf::from("std.jsonnet")), 0, 0)),25 || format!("std.format of {}", str),26 || {27 Ok(match vals {28 Val::Arr(vals) => Val::Str(format_arr(&str, &vals.evaluated()?)?.into()),29 Val::Obj(obj) => Val::Str(format_obj(&str, &obj)?.into()),30 o => Val::Str(format_arr(&str, &[o])?.into()),31 })32 },33 )34}3536thread_local! {37 pub static INTRINSICS: HashMap<&'static str, fn(Context, &Option<ExprLocation>, &ArgsDesc) -> Result<Val>> = {38 let mut out: HashMap<&'static str, _> = HashMap::new();39 out.insert("length", intrinsic_length);40 out41 };42}4344fn intrinsic_length(context: Context, _loc: &Option<ExprLocation>, args: &ArgsDesc) -> Result<Val> {45 Ok(parse_args!(context, "length", args, 1, [46 0, x: ty!((str | obj | [any]));47 ], {48 Ok(match x {49 Val::Str(n) => Val::Num(n.chars().count() as f64),50 Val::Arr(a) => Val::Num(a.len() as f64),51 Val::Obj(o) => Val::Num(52 o.fields_visibility()53 .into_iter()54 .filter(|(_k, v)| *v)55 .count() as f64,56 ),57 _ => unreachable!(),58 })59 })?)60}6162#[allow(clippy::cognitive_complexity)]63pub fn call_builtin(64 context: Context,65 loc: &Option<ExprLocation>,66 name: &str,67 args: &ArgsDesc,68) -> Result<Val> {69 Ok(match name as &str {70 "length" => parse_args!(context, "length", args, 1, [71 0, x: ty!((str | obj | [any]));72 ], {73 Ok(match x {74 Val::Str(n) => Val::Num(n.chars().count() as f64),75 Val::Arr(a) => Val::Num(a.len() as f64),76 Val::Obj(o) => Val::Num(77 o.fields_visibility()78 .into_iter()79 .filter(|(_k, v)| *v)80 .count() as f64,81 ),82 _ => unreachable!(),83 })84 })?,85 "type" => parse_args!(context, "type", args, 1, [86 0, x: ty!(any);87 ], {88 Ok(Val::Str(x.value_type().name().into()))89 })?,90 "makeArray" => parse_args!(context, "makeArray", args, 2, [91 0, sz: ty!(number((Some(0.0))..(None))) => Val::Num;92 1, func: ty!(fn.any) => Val::Func;93 ], {94 let mut out = Vec::with_capacity(sz as usize);95 for i in 0..sz as usize {96 out.push(LazyVal::new_resolved(func.evaluate_values(97 Context::new(),98 &[Val::Num(i as f64)]99 )?))100 }101 Ok(Val::Arr(out.into()))102 })?,103 "codepoint" => parse_args!(context, "codepoint", args, 1, [104 0, str: ty!(char) => Val::Str;105 ], {106 Ok(Val::Num(str.chars().take(1).next().unwrap() as u32 as f64))107 })?,108 "objectFieldsEx" => parse_args!(context, "objectFieldsEx", args, 2, [109 0, obj: ty!(obj) => Val::Obj;110 1, inc_hidden: ty!(bool) => Val::Bool;111 ], {112 let mut out = obj.fields_visibility()113 .into_iter()114 .filter(|(_k, v)| *v || inc_hidden)115 .map(|(k, _v)|k)116 .collect::<Vec<_>>();117 out.sort();118 Ok(Val::Arr(out.into_iter().map(Val::Str).collect::<Vec<_>>().into()))119 })?,120 "objectHasEx" => parse_args!(context, "objectHasEx", args, 3, [121 0, obj: ty!(obj) => Val::Obj;122 1, f: ty!(str) => Val::Str;123 2, inc_hidden: ty!(bool) => Val::Bool;124 ], {125 Ok(Val::Bool(126 obj.fields_visibility()127 .into_iter()128 .filter(|(_k, v)| *v || inc_hidden)129 .any(|(k, _v)| *k == *f),130 ))131 })?,132 // faster133 "slice" => parse_args!(context, "slice", args, 4, [134 0, indexable: ty!((str | [any]));135 1, index: ty!((num | null));136 2, end: ty!((num | null));137 3, step: ty!((num | null));138 ], {139 let index = match index {140 Val::Num(v) => v as usize,141 Val::Null => 0,142 _ => unreachable!(),143 };144 let end = match end {145 Val::Num(v) => v as usize,146 Val::Null => match &indexable {147 Val::Str(s) => s.chars().count(),148 Val::Arr(v) => v.len(),149 _ => unreachable!()150 },151 _ => unreachable!()152 };153 let step = match step {154 Val::Num(v) => v as usize,155 Val::Null => 1,156 _ => unreachable!()157 };158 match &indexable {159 Val::Str(s) => {160 Ok(Val::Str((s.chars().skip(index).take(end-index).step_by(step).collect::<String>()).into()))161 }162 Val::Arr(arr) => {163 Ok(Val::Arr((arr.iter().skip(index).take(end-index).step_by(step).collect::<Result<Vec<Val>>>()?).into()))164 }165 _ => unreachable!()166 }167 })?,168 "primitiveEquals" => parse_args!(context, "primitiveEquals", args, 2, [169 0, a: ty!(any);170 1, b: ty!(any);171 ], {172 Ok(Val::Bool(primitive_equals(&a, &b)?))173 })?,174 // faster175 "equals" => parse_args!(context, "equals", args, 2, [176 0, a: ty!(any);177 1, b: ty!(any);178 ], {179 Ok(Val::Bool(equals(&a, &b)?))180 })?,181 "modulo" => parse_args!(context, "modulo", args, 2, [182 0, a: ty!(num) => Val::Num;183 1, b: ty!(num) => Val::Num;184 ], {185 Ok(Val::Num(a % b))186 })?,187 "mod" => parse_args!(context, "mod", args, 2, [188 0, a: ty!((num | str));189 1, b: ty!(any);190 ], {191 match (a, b) {192 (Val::Num(a), Val::Num(b)) => Ok(Val::Num(a % b)),193 (Val::Str(str), vals) => std_format(str, vals),194 (a, b) => throw!(BinaryOperatorDoesNotOperateOnValues(BinaryOpType::Mod, a.value_type(), b.value_type()))195 }196 })?,197 "floor" => parse_args!(context, "floor", args, 1, [198 0, x: ty!(num) => Val::Num;199 ], {200 Ok(Val::Num(x.floor()))201 })?,202 "log" => parse_args!(context, "log", args, 1, [203 0, n: ty!(num) => Val::Num;204 ], {205 Ok(Val::Num(n.ln()))206 })?,207 "trace" => parse_args!(context, "trace", args, 2, [208 0, str: ty!(str) => Val::Str;209 1, rest: ty!(any);210 ], {211 eprint!("TRACE:");212 if let Some(loc) = loc {213 with_state(|s|{214 let locs = s.map_source_locations(&loc.0, &[loc.1]);215 eprint!(" {}:{}", loc.0.file_name().unwrap().to_str().unwrap(), locs[0].line);216 });217 }218 eprintln!(" {}", str);219 Ok(rest)220 })?,221 "pow" => parse_args!(context, "pow", args, 2, [222 0, x: ty!(num) => Val::Num;223 1, n: ty!(num) => Val::Num;224 ], {225 Ok(Val::Num(x.powf(n)))226 })?,227 "extVar" => parse_args!(context, "extVar", args, 1, [228 0, x: ty!(str) => Val::Str;229 ], {230 Ok(with_state(|s| s.settings().ext_vars.get(&x).cloned()).ok_or(UndefinedExternalVariable(x))?)231 })?,232 "native" => parse_args!(context, "native", args, 1, [233 0, x: ty!(str) => Val::Str;234 ], {235 Ok(with_state(|s| s.settings().ext_natives.get(&x).cloned()).map(|v| Val::Func(Rc::new(FuncVal::NativeExt(x.clone(), v)))).ok_or(UndefinedExternalFunction(x))?)236 })?,237 "filter" => parse_args!(context, "filter", args, 2, [238 0, func: ty!(fn.any) => Val::Func;239 1, arr: ty!([any]) => Val::Arr;240 ], {241 let mut out = Vec::new();242 for item in arr.iter() {243 let item = item?;244 if func245 .evaluate_values(context.clone(), &[item.clone()])?246 .try_cast_bool("filter predicate")? {247 out.push(item);248 }249 }250 Ok(Val::Arr(out.into()))251 })?,252 "foldl" => parse_args!(context, "foldl", args, 3, [253 0, func: ty!(fn.any) => Val::Func;254 1, arr: ty!([any]) => Val::Arr;255 2, init: ty!(any);256 ], {257 let mut acc = init;258 for i in arr.iter() {259 acc = func.evaluate_values(context.clone(), &[acc, i?])?;260 }261 Ok(acc)262 })?,263 "foldr" => parse_args!(context, "foldr", args, 3, [264 0, func: ty!(fn.any) => Val::Func;265 1, arr: ty!([any]) => Val::Arr;266 2, init: ty!(any);267 ], {268 let mut acc = init;269 for i in arr.iter().rev() {270 acc = func.evaluate_values(context.clone(), &[acc, i?])?;271 }272 Ok(acc)273 })?,274 #[allow(non_snake_case)]275 "sortImpl" => parse_args!(context, "sort", args, 2, [276 0, arr: ty!([any]) => Val::Arr;277 1, keyF: ty!(fn.any) => Val::Func;278 ], {279 if arr.len() <= 1 {280 return Ok(Val::Arr(arr))281 }282 Ok(Val::Arr(ArrValue::Eager(sort::sort(context, arr.evaluated()?, &keyF)?)))283 })?,284 // faster285 "format" => parse_args!(context, "format", args, 2, [286 0, str: ty!(str) => Val::Str;287 1, vals: ty!(any)288 ], {289 std_format(str, vals)290 })?,291 "range" => parse_args!(context, "range", args, 2, [292 0, from: ty!(num) => Val::Num;293 1, to: ty!(num) => Val::Num;294 ], {295 let mut out = Vec::with_capacity((1+to as usize-from as usize).max(0));296 for i in from as usize..=to as usize {297 out.push(Val::Num(i as f64));298 }299 Ok(Val::Arr(out.into()))300 })?,301 "char" => parse_args!(context, "char", args, 1, [302 0, n: ty!(num) => Val::Num;303 ], {304 let mut out = String::new();305 out.push(std::char::from_u32(n as u32).ok_or_else(||306 InvalidUnicodeCodepointGot(n as u32)307 )?);308 Ok(Val::Str(out.into()))309 })?,310 "encodeUTF8" => parse_args!(context, "encodeUTF8", args, 1, [311 0, str: ty!(str) => Val::Str;312 ], {313 Ok(Val::Arr((str.bytes().map(|b| Val::Num(b as f64)).collect::<Vec<Val>>()).into()))314 })?,315 "md5" => parse_args!(context, "md5", args, 1, [316 0, str: ty!(str) => Val::Str;317 ], {318 Ok(Val::Str(format!("{:x}", md5::compute(&str.as_bytes())).into()))319 })?,320 "base64" => parse_args!(context, "base64", args, 1, [321 0, input: ty!((str | [num]));322 ], {323 Ok(Val::Str(match input {324 Val::Str(s) => {325 base64::encode(s.bytes().collect::<Vec<_>>()).into()326 },327 Val::Arr(a) => {328 base64::encode(a.iter().map(|v| {329 Ok(v?.clone().unwrap_num()? as u8)330 }).collect::<Result<Vec<_>>>()?).into()331 },332 _ => unreachable!()333 }))334 })?,335 "join" => parse_args!(context, "join", args, 2, [336 0, sep: ty!((str | [any]));337 1, arr: ty!([any]) => Val::Arr;338 ], {339 Ok(match sep {340 Val::Arr(joiner_items) => {341 let mut out = Vec::new();342343 let mut first = true;344 for item in arr.iter() {345 let item = item?.clone();346 if let Val::Arr(items) = item {347 if !first {348 out.reserve(joiner_items.len());349 // TODO: extend350 for item in joiner_items.iter() {351 out.push(item?);352 }353 }354 first = false;355 out.reserve(items.len());356 // TODO: extend357 for item in items.iter() {358 out.push(item?);359 }360 } else {361 throw!(RuntimeError("in std.join all items should be arrays".into()));362 }363 }364365 Val::Arr(out.into())366 },367 Val::Str(sep) => {368 let mut out = String::new();369370 let mut first = true;371 for item in arr.iter() {372 let item = item?.clone();373 if let Val::Str(item) = item {374 if !first {375 out += &sep;376 }377 first = false;378 out += &item;379 } else {380 throw!(RuntimeError("in std.join all items should be strings".into()));381 }382 }383384 Val::Str(out.into())385 },386 _ => unreachable!()387 })388 })?,389 // faster390 "escapeStringJson" => parse_args!(context, "escapeStringJson", args, 1, [391 0, str_: ty!(str) => Val::Str;392 ], {393 Ok(Val::Str(escape_string_json(&str_).into()))394 })?,395 // faster396 "manifestJsonEx" => parse_args!(context, "manifestJsonEx", args, 2, [397 0, value: ty!(any);398 1, indent: ty!(str) => Val::Str;399 ], {400 Ok(Val::Str(manifest_json_ex(&value, &ManifestJsonOptions {401 padding: &indent,402 mtype: ManifestType::Std,403 })?.into()))404 })?,405 // faster406 "reverse" => parse_args!(context, "reverse", args, 1, [407 0, value: ty!([any]) => Val::Arr;408 ], {409 Ok(Val::Arr(value.reversed()))410 })?,411 "id" => parse_args!(context, "id", args, 1, [412 0, v: ty!(any);413 ], {414 Ok(v)415 })?,416 name => throw!(IntrinsicNotFound(name.into())),417 })418}crates/jrsonnet-types/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-types/src/lib.rs
+++ b/crates/jrsonnet-types/src/lib.rs
@@ -3,6 +3,7 @@
#[macro_export]
macro_rules! ty {
([$inner:tt]) => {{
+ use $crate::{ComplexValType, ValType, ty};
static VAL: &'static ComplexValType = &ty!($inner);
match VAL {
ComplexValType::Any => ComplexValType::Simple(ValType::Arr),
@@ -10,43 +11,43 @@
}
}};
(bool) => {
- ComplexValType::Simple(ValType::Bool)
+ $crate::ComplexValType::Simple($crate::ValType::Bool)
};
(null) => {
- ComplexValType::Simple(ValType::Null)
+ $crate::ComplexValType::Simple($crate::ValType::Null)
};
(str) => {
- ComplexValType::Simple(ValType::Str)
+ $crate::ComplexValType::Simple($crate::ValType::Str)
};
(char) => {
- ComplexValType::Char
+ $crate::ComplexValType::Char
};
(num) => {
- ComplexValType::Simple(ValType::Num)
+ $crate::ComplexValType::Simple($crate::ValType::Num)
};
(number(($min:expr)..($max:expr))) => {{
- ComplexValType::BoundedNumber($min, $max)
+ $crate::ComplexValType::BoundedNumber($min, $max)
}};
(obj) => {
- ComplexValType::Simple(ValType::Obj)
+ $crate::ComplexValType::Simple($crate::ValType::Obj)
};
(any) => {
- ComplexValType::Any
+ $crate::ComplexValType::Any
};
(fn.any) => {
- ComplexValType::Simple(ValType::Func)
+ $crate::ComplexValType::Simple($crate::ValType::Func)
};
(($($a:tt) |+)) => {{
- static CONTENTS: &'static [ComplexValType] = &[
+ static CONTENTS: &'static [$crate::ComplexValType] = &[
$(ty!($a)),+
];
- ComplexValType::UnionRef(CONTENTS)
+ $crate::ComplexValType::UnionRef(CONTENTS)
}};
(($($a:tt) &+)) => {{
- static CONTENTS: &'static [ComplexValType] = &[
+ static CONTENTS: &'static [$crate::ComplexValType] = &[
$(ty!($a)),+
];
- ComplexValType::SumRef(CONTENTS)
+ $crate::ComplexValType::SumRef(CONTENTS)
}};
}