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

difftreelog

doc: review issues

Yaroslav Bolyukin2022-10-15parent: #70f3783.patch.diff
in: master

19 files changed

modifiedbindings/jsonnet/src/import.rsdiffbeforeafterboth
9393
94/// # Safety94/// # Safety
95///95///
96/// Caller should pass correct callback function96/// It should be safe to call `cb` using valid values with passed `ctx`
97#[no_mangle]97#[no_mangle]
98pub unsafe extern "C" fn jsonnet_import_callback(98pub unsafe extern "C" fn jsonnet_import_callback(
99 vm: &State,99 vm: &State,
109109
110/// # Safety110/// # Safety
111///111///
112/// Caller should pass correct path: it should contain correct utf-8, and be \0-terminated112/// `path` should be a NUL-terminated string
113#[no_mangle]113#[no_mangle]
114pub unsafe extern "C" fn jsonnet_jpath_add(vm: &State, v: *const c_char) {114pub unsafe extern "C" fn jsonnet_jpath_add(vm: &State, path: *const c_char) {
115 let cstr = CStr::from_ptr(v);115 let cstr = CStr::from_ptr(path);
116 let path = PathBuf::from(cstr.to_str().unwrap());116 let path = PathBuf::from(cstr.to_str().unwrap());
117 let any_resolver = vm.import_resolver();117 let any_resolver = vm.import_resolver();
118 let resolver = any_resolver118 let resolver = any_resolver
modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
41 let str = OsStr::from_bytes(input.to_bytes());41 let str = OsStr::from_bytes(input.to_bytes());
42 Cow::Borrowed(Path::new(str))42 Cow::Borrowed(Path::new(str))
43 }43 }
44 #[cfg(target_family = "windows")]44 #[cfg(not(target_family = "unix"))]
45 {45 {
46 use std::os::windows::ffi::OsStringExt;
47 let str = input.to_str().expect("input is not utf8");46 let string = input.to_str().expect("bad utf-8");
48 let wide = str.encode_utf16().collect::<Vec<_>>();
49 let wide = OsString::from_wide(&wide);
50 Cow::Owned(PathBuf::new(wide))47 Cow::Borrowed(string.as_ref())
51 }48 }
52 #[cfg(not(any(target_family = "unix", target_family = "windows")))]
53 {
54 compile_error!("unsupported os")
55 }
56}49}
5750
58unsafe fn unparse_path(input: &Path) -> Cow<CStr> {51unsafe fn unparse_path(input: &Path) -> Cow<CStr> {
62 let str = CString::new(input.as_os_str().as_bytes()).expect("input has zero byte in it");55 let str = CString::new(input.as_os_str().as_bytes()).expect("input has zero byte in it");
63 Cow::Owned(str)56 Cow::Owned(str)
64 }57 }
65 #[cfg(not(any(target_family = "unix", target_family = "windows")))]58 #[cfg(not(target_family = "unix"))]
66 {59 {
60 let str = input.as_os_str().to_str().expect("bad utf-8");
67 compile_error!("unsupported os")61 let cstr = CString::new(str).expect("input has NUL inside");
62 Cow::Owned(cstr)
68 }63 }
69}64}
7065
169///164///
170/// # Safety165/// # Safety
171///166///
172/// `filename` should be a \0-terminated string167/// `filename` should be a NUL-terminated string
173#[no_mangle]168#[no_mangle]
174pub unsafe extern "C" fn jsonnet_evaluate_file(169pub unsafe extern "C" fn jsonnet_evaluate_file(
175 vm: &State,170 vm: &State,
200///195///
201/// # Safety196/// # Safety
202///197///
203/// `filename`, `snippet` should be a \0-terminated strings198/// `filename`, `snippet` should be a NUL-terminated strings
204#[no_mangle]199#[no_mangle]
205pub unsafe extern "C" fn jsonnet_evaluate_snippet(200pub unsafe extern "C" fn jsonnet_evaluate_snippet(
206 vm: &State,201 vm: &State,
modifiedbindings/jsonnet/src/native.rsdiffbeforeafterboth
65/// # Safety65/// # Safety
66///66///
67/// `vm` should be a vm allocated by `jsonnet_make`67/// `vm` should be a vm allocated by `jsonnet_make`
68/// `name` should be a NUL-terminated string
68/// `cb` should be a correct function pointer69/// `cb` should be a function pointer
69/// `raw_params` should point to a NULL-terminated string array70/// `raw_params` should point to a NULL-terminated array of NUL-terminated strings
70/// `name`, `raw_params` elements should be a \0-terminated strings
71#[no_mangle]71#[no_mangle]
72pub unsafe extern "C" fn jsonnet_native_callback(72pub unsafe extern "C" fn jsonnet_native_callback(
73 vm: &State,73 vm: &State,
modifiedbindings/jsonnet/src/val_make.rsdiffbeforeafterboth
12///12///
13/// # Safety13/// # Safety
14///14///
15/// `v` should be a \0-terminated string15/// `v` should be a NUL-terminated string
16#[no_mangle]16#[no_mangle]
17pub unsafe extern "C" fn jsonnet_json_make_string(_vm: &State, val: *const c_char) -> *mut Val {17pub unsafe extern "C" fn jsonnet_json_make_string(_vm: &State, val: *const c_char) -> *mut Val {
18 let val = CStr::from_ptr(val);18 let val = CStr::from_ptr(val);
modifiedbindings/jsonnet/src/val_modify.rsdiffbeforeafterboth
11///11///
12/// # Safety12/// # Safety
13///13///
14/// `arr` should be correct pointer to array value allocated by make_array, or returned by other library call14/// `arr` should be a pointer to array value allocated by make_array, or returned by other library call
15/// `val` should be correct pointer to value allocated using this library15/// `val` should be a pointer to value allocated using this library
16#[no_mangle]16#[no_mangle]
17pub unsafe extern "C" fn jsonnet_json_array_append(_vm: &State, arr: &mut Val, val: &Val) {17pub unsafe extern "C" fn jsonnet_json_array_append(_vm: &State, arr: &mut Val, val: &Val) {
18 match arr {18 match arr {
35///35///
36/// # Safety36/// # Safety
37///37///
38/// `obj` should be a valid pointer to object value allocated by `make_object`, or returned by other library call38/// `obj` should be a pointer to object value allocated by `make_object`, or returned by other library call
39/// `name` should be \0-terminated string39/// `name` should be NUL-terminated string
40#[no_mangle]40#[no_mangle]
41pub unsafe extern "C" fn jsonnet_json_object_append(41pub unsafe extern "C" fn jsonnet_json_object_append(
42 _vm: &State,42 _vm: &State,
modifiedbindings/jsonnet/src/vars_tlas.rsdiffbeforeafterboth
44
5use jrsonnet_evaluator::State;5use jrsonnet_evaluator::State;
66
7/// Bind a Jsonnet external var to the given string.7/// Binds a Jsonnet external variable to the given string.
8///8///
9/// Argument values are copied so memory should be managed by caller.9/// Argument values are copied so memory should be managed by the caller.
10///10///
11/// # Safety11/// # Safety
12///12///
13/// Caller should pass correct pointers as `name` and `code`, they need to be \0-terminated strings13/// `name`, `code` should be a NUL-terminated strings
14#[no_mangle]14#[no_mangle]
15pub unsafe extern "C" fn jsonnet_ext_var(vm: &State, name: *const c_char, value: *const c_char) {15pub unsafe extern "C" fn jsonnet_ext_var(vm: &State, name: *const c_char, value: *const c_char) {
16 let name = CStr::from_ptr(name);16 let name = CStr::from_ptr(name);
27 )27 )
28}28}
2929
30/// Bind a Jsonnet external var to the given code.30/// Binds a Jsonnet external variable to the given code.
31///31///
32/// Argument values are copied so memory should be managed by caller.32/// Argument values are copied so memory should be managed by the caller.
33///33///
34/// # Safety34/// # Safety
35///35///
36/// Caller should pass correct pointers as `name` and `code`, they need to be \0-terminated strings36/// `name`, `code` should be a NUL-terminated strings
37#[no_mangle]37#[no_mangle]
38pub unsafe extern "C" fn jsonnet_ext_code(vm: &State, name: *const c_char, code: *const c_char) {38pub unsafe extern "C" fn jsonnet_ext_code(vm: &State, name: *const c_char, code: *const c_char) {
39 let name = CStr::from_ptr(name);39 let name = CStr::from_ptr(name);
51 .expect("can't parse ext code")51 .expect("can't parse ext code")
52}52}
5353
54/// Bind a string top-level argument for a top-level parameter.54/// Binds a top-level string argument for a top-level parameter.
55///55///
56/// Argument values are copied so memory should be managed by caller.56/// Argument values are copied so memory should be managed by the caller.
57///57///
58/// # Safety58/// # Safety
59///59///
60/// Caller should pass correct pointers as `name` and `value`, they need to be \0-terminated strings60/// `name`, `value` should be a NUL-terminated strings
61#[no_mangle]61#[no_mangle]
62pub unsafe extern "C" fn jsonnet_tla_var(vm: &State, name: *const c_char, value: *const c_char) {62pub unsafe extern "C" fn jsonnet_tla_var(vm: &State, name: *const c_char, value: *const c_char) {
63 let name = CStr::from_ptr(name);63 let name = CStr::from_ptr(name);
68 )68 )
69}69}
7070
71/// Bind a code top-level argument for a top-level parameter.71/// Binds a top-level code argument for a top-level parameter.
72///72///
73/// Argument values are copied so memory should be managed by caller.73/// Argument values are copied so memory should be managed by the caller.
74///74///
75/// # Safety75/// # Safety
76///76///
77/// Caller should pass correct pointers as `name` and `code`, they need to be \0-terminated strings77/// `name`, `code` should be a NUL-terminated strings
78#[no_mangle]78#[no_mangle]
79pub unsafe extern "C" fn jsonnet_tla_code(vm: &State, name: *const c_char, code: *const c_char) {79pub unsafe extern "C" fn jsonnet_tla_code(vm: &State, name: *const c_char, code: *const c_char) {
80 let name = CStr::from_ptr(name);80 let name = CStr::from_ptr(name);
modifiedcrates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth
20 }20 }
21}21}
2222
23/// Context keeps information about current lexical code location
24///
25/// This information includes local variables, top-level object (`$`), current object (`this`), and super object (`super`)
23#[derive(Debug, Clone, Trace)]26#[derive(Debug, Clone, Trace)]
24pub struct Context(Cc<ContextInternals>);27pub struct Context(Cc<ContextInternals>);
25impl Context {28impl Context {
160 extend: Some(parent),163 extend: Some(parent),
161 }164 }
162 }165 }
166 /// # Panics
167 /// If `name` is already bound
163 pub fn bind(&mut self, name: IStr, value: Thunk<Val>) -> &mut Self {168 pub fn bind(&mut self, name: IStr, value: Thunk<Val>) -> &mut Self {
164 self.bindings.insert(name, value);169 let old = self.bindings.insert(name, value);
170 assert!(old.is_none(), "variable bound twice in single context call");
165 self171 self
166 }172 }
167 pub fn build(self) -> Context {173 pub fn build(self) -> Context {
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
6767
68type FunctionSignature = Vec<(Option<IStr>, bool)>;68type FunctionSignature = Vec<(Option<IStr>, bool)>;
6969
70/// Possible errors
71#[allow(missing_docs)]
70#[derive(Error, Debug, Clone, Trace)]72#[derive(Error, Debug, Clone, Trace)]
73#[non_exhaustive]
71pub enum Error {74pub enum Error {
72 #[error("intrinsic not found: {0}")]75 #[error("intrinsic not found: {0}")]
73 IntrinsicNotFound(IStr),76 IntrinsicNotFound(IStr),
217 }220 }
218}221}
219222
223/// Single stack trace frame
220#[derive(Clone, Debug, Trace)]224#[derive(Clone, Debug, Trace)]
221pub struct StackTraceElement {225pub struct StackTraceElement {
226 /// Source of this frame
227 /// Some frames only act as description, without attached source
222 pub location: Option<ExprLocation>,228 pub location: Option<ExprLocation>,
229 /// Frame description
223 pub desc: String,230 pub desc: String,
224}231}
225#[derive(Debug, Clone, Trace)]232#[derive(Debug, Clone, Trace)]
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
269 }269 }
270 }270 }
271 let this = builder.build();271 let this = builder.build();
272 let _ctx = ctx272 fctx.fill(ctx.extend(GcHashMap::new(), None, None, Some(this.clone())));
273 .extend(GcHashMap::new(), None, None, Some(this.clone()))
274 .into_future(fctx);
275 Ok(this)273 Ok(this)
276}274}
277275
356 ctx: Context,354 ctx: Context,
357 value: &LocExpr,355 value: &LocExpr,
358 args: &ArgsDesc,356 args: &ArgsDesc,
359 loc: CallLocation,357 loc: CallLocation<'_>,
360 tailstrict: bool,358 tailstrict: bool,
361) -> Result<Val> {359) -> Result<Val> {
362 let value = evaluate(s.clone(), ctx.clone(), value)?;360 let value = evaluate(s.clone(), ctx.clone(), value)?;
602 }600 }
603 Slice(value, desc) => {601 Slice(value, desc) => {
604 fn parse_idx<T: Typed>(602 fn parse_idx<T: Typed>(
605 loc: CallLocation,603 loc: CallLocation<'_>,
606 s: State,604 s: State,
607 ctx: &Context,605 ctx: &Context,
608 expr: &Option<LocExpr>,606 expr: &Option<LocExpr>,
modifiedcrates/jrsonnet-evaluator/src/function/builtin.rsdiffbeforeafterboth
28 &self,
29 s: State,
30 ctx: Context,
31 loc: CallLocation<'_>,
32 args: &dyn ArgsLike,
33 ) -> Result<Val>;
28}34}
80 &self,
81 s: State,
82 ctx: Context,
83 _loc: CallLocation<'_>,
84 args: &dyn ArgsLike,
85 ) -> Result<Val> {
74 let args = parse_builtin_call(s.clone(), ctx, &self.params, args, true)?;86 let args = parse_builtin_call(s.clone(), ctx, &self.params, args, true)?;
modifiedcrates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth
18pub mod native;18pub mod native;
19pub mod parse;19pub mod parse;
2020
21/// Function callsite location.
22/// Either from other jsonnet code, specified by expression location, or from native (without location).
21#[derive(Clone, Copy)]23#[derive(Clone, Copy)]
22pub struct CallLocation<'l>(pub Option<&'l ExprLocation>);24pub struct CallLocation<'l>(pub Option<&'l ExprLocation>);
23impl<'l> CallLocation<'l> {25impl<'l> CallLocation<'l> {
26 /// Construct new location for calls coming from specified jsonnet expression location.
24 pub const fn new(loc: &'l ExprLocation) -> Self {27 pub const fn new(loc: &'l ExprLocation) -> Self {
25 Self(Some(loc))28 Self(Some(loc))
26 }29 }
27}30}
28impl CallLocation<'static> {31impl CallLocation<'static> {
32 /// Construct new location for calls coming from native code.
29 pub const fn native() -> Self {33 pub const fn native() -> Self {
30 Self(None)34 Self(None)
31 }35 }
32}36}
3337
34/// Function implemented in jsonnet38/// Represents Jsonnet function defined in code.
35#[derive(Debug, PartialEq, Trace)]39#[derive(Debug, PartialEq, Trace)]
36pub struct FuncDesc {40pub struct FuncDesc {
37 /// In expressions like41 /// # Example
42 ///
43 /// In expressions like this, deducted to `a`, unspecified otherwise.
38 /// ```jsonnet44 /// ```jsonnet
39 /// local a = function() ...45 /// local a = function() ...
40 /// local a() ...46 /// local a() ...
41 /// { a: function() ... }47 /// { a: function() ... }
42 /// { a() = ... }48 /// { a() = ... }
43 /// ```49 /// ```
44 ///
45 /// Deducted to `a`, unspecified otherwise
46 pub name: IStr,50 pub name: IStr,
47 /// Context, in which this function was evaluated51 /// Context, in which this function was evaluated.
48 ///52 ///
53 /// # Example
49 /// I.e in54 /// In
50 /// ```jsonnet55 /// ```jsonnet
51 /// local a = 2;56 /// local a = 2;
52 /// function() ...57 /// function() ...
53 /// ```58 /// ```
54 /// context will contain `a`59 /// context will contain `a`.
55 pub ctx: Context,60 pub ctx: Context,
5661
62 /// Function parameter definition
57 pub params: ParamsDesc,63 pub params: ParamsDesc,
64 /// Function body
58 pub body: LocExpr,65 pub body: LocExpr,
59}66}
60impl FuncDesc {67impl FuncDesc {
82 }89 }
83}90}
8491
85/// Any possible function value, including plain functions and user-provided builtins92/// Represents a Jsonnet function value, including plain functions and user-provided builtins.
86#[allow(clippy::module_name_repetitions)]93#[allow(clippy::module_name_repetitions)]
87#[derive(Trace, Clone)]94#[derive(Trace, Clone)]
88pub enum FuncVal {95pub enum FuncVal {
89 /// std.id96 /// Identity function, kept this way for comparsions.
90 Id,97 Id,
91 /// Plain function implemented in jsonnet98 /// Plain function implemented in jsonnet.
92 Normal(Cc<FuncDesc>),99 Normal(Cc<FuncDesc>),
93 /// Standard library function100 /// Standard library function.
94 StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin),101 StaticBuiltin(#[trace(skip)] &'static dyn StaticBuiltin),
95 /// User-provided function102 /// User-provided function.
96 Builtin(Cc<TraceBox<dyn Builtin>>),103 Builtin(Cc<TraceBox<dyn Builtin>>),
97}104}
98105
110}117}
111118
112impl FuncVal {119impl FuncVal {
113 pub fn into_native<D: NativeDesc>(self) -> D::Value {120 /// Amount of non-default required arguments
114 D::into_native(self)
115 }
116 pub fn params_len(&self) -> usize {121 pub fn params_len(&self) -> usize {
117 match self {122 match self {
118 Self::Id => 1,123 Self::Id => 1,
121 Self::Builtin(i) => i.params().iter().filter(|p| !p.has_default).count(),126 Self::Builtin(i) => i.params().iter().filter(|p| !p.has_default).count(),
122 }127 }
123 }128 }
129 /// Function name, as defined in code.
124 pub fn name(&self) -> IStr {130 pub fn name(&self) -> IStr {
125 match self {131 match self {
126 Self::Id => "id".into(),132 Self::Id => "id".into(),
129 Self::Builtin(builtin) => builtin.name().into(),135 Self::Builtin(builtin) => builtin.name().into(),
130 }136 }
131 }137 }
138 /// Call function using arguments evaluated in specified `call_ctx` [`Context`].
139 ///
140 /// If `tailstrict` is specified - then arguments will be evaluated before being passed to function body.
132 pub fn evaluate(141 pub fn evaluate(
133 &self,142 &self,
134 s: State,143 s: State,
135 call_ctx: Context,144 call_ctx: Context,
136 loc: CallLocation,145 loc: CallLocation<'_>,
137 args: &dyn ArgsLike,146 args: &dyn ArgsLike,
138 tailstrict: bool,147 tailstrict: bool,
139 ) -> Result<Val> {148 ) -> Result<Val> {
156 Self::Builtin(b) => b.call(s, call_ctx, loc, args),165 Self::Builtin(b) => b.call(s, call_ctx, loc, args),
157 }166 }
158 }167 }
168 /// Helper method, which calls [`Self::evaluate`] with sensible defaults for native code.
159 pub fn evaluate_simple(&self, s: State, args: &dyn ArgsLike) -> Result<Val> {169 pub fn evaluate_simple(&self, s: State, args: &dyn ArgsLike) -> Result<Val> {
160 self.evaluate(s, Context::default(), CallLocation::native(), args, true)170 self.evaluate(s, Context::default(), CallLocation::native(), args, true)
161 }171 }
162172 /// Convert jsonnet function to plain `Fn` value.
173 pub fn into_native<D: NativeDesc>(self) -> D::Value {
174 D::into_native(self)
175 }
176
177 /// Is this function an indentity function.
178 ///
179 /// Currently only works for builtin `std.id`, aka `Self::Id` value, `function(x) x` defined by jsonnet will not count as identity.
163 pub const fn is_identity(&self) -> bool {180 pub const fn is_identity(&self) -> bool {
164 matches!(self, Self::Id)181 matches!(self, Self::Id)
165 }182 }
183 /// Identity function value.
166 pub const fn identity() -> Self {184 pub const fn identity() -> Self {
167 Self::Id185 Self::Id
168 }186 }
modifiedcrates/jrsonnet-evaluator/src/gc.rsdiffbeforeafterboth
22}22}
2323
24impl<T: ?Sized + Trace> Trace for TraceBox<T> {24impl<T: ?Sized + Trace> Trace for TraceBox<T> {
25 fn trace(&self, tracer: &mut Tracer) {25 fn trace(&self, tracer: &mut Tracer<'_>) {
26 self.0.trace(tracer);26 self.0.trace(tracer);
27 }27 }
2828
92where92where
93 V: Trace,93 V: Trace,
94{94{
95 fn trace(&self, tracer: &mut jrsonnet_gcmodule::Tracer) {95 fn trace(&self, tracer: &mut Tracer<'_>) {
96 for v in &self.0 {96 for v in &self.0 {
97 v.trace(tracer);97 v.trace(tracer);
98 }98 }
133 K: Trace,133 K: Trace,
134 V: Trace,134 V: Trace,
135{135{
136 fn trace(&self, tracer: &mut jrsonnet_gcmodule::Tracer) {136 fn trace(&self, tracer: &mut Tracer<'_>) {
137 for (k, v) in &self.0 {137 for (k, v) in &self.0 {
138 k.trace(tracer);138 k.trace(tracer);
139 v.trace(tracer);139 v.trace(tracer);
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
1//! jsonnet interpreter implementation
2
3#![deny(unsafe_op_in_unsafe_fn)]
1#![warn(clippy::all, clippy::nursery, clippy::pedantic)]4#![warn(
5 clippy::all,
6 clippy::nursery,
7 clippy::pedantic,
8 // missing_docs,
9 elided_lifetimes_in_paths,
10 explicit_outlives_requirements,
11 noop_method_call,
12 single_use_lifetimes,
13 variant_size_differences,
14 rustdoc::all
15)]
2#![allow(16#![allow(
3 macro_expanded_macro_exports_accessed_by_absolute_paths,17 macro_expanded_macro_exports_accessed_by_absolute_paths,
67use trace::{CompactFormat, TraceFormat};81use trace::{CompactFormat, TraceFormat};
68pub use val::{ManifestFormat, Thunk, Val};82pub use val::{ManifestFormat, Thunk, Val};
6983
84/// Thunk without bound `super`/`this`
85/// object inheritance may be overriden multiple times, and will be fixed only on field read
70pub trait Unbound: Trace {86pub trait Unbound: Trace {
87 /// Type of value after object context is bound
71 type Bound;88 type Bound;
89 /// Create value bound to specified object context
72 fn bind(&self, s: State, sup: Option<ObjValue>, this: Option<ObjValue>) -> Result<Self::Bound>;90 fn bind(&self, s: State, sup: Option<ObjValue>, this: Option<ObjValue>) -> Result<Self::Bound>;
73}91}
7492
93/// Object fields may, or may not depend on `this`/`super`, this enum allows cheaper reuse of object-independent fields for native code
94/// Standard jsonnet fields are always unbound
75#[derive(Clone, Trace)]95#[derive(Clone, Trace)]
76pub enum LazyBinding {96pub enum MaybeUnbound {
97 /// Value needs to be bound to `this`/`super`
77 Bindable(Cc<TraceBox<dyn Unbound<Bound = Thunk<Val>>>>),98 Unbound(Cc<TraceBox<dyn Unbound<Bound = Thunk<Val>>>>),
99 /// Value is object-independent
78 Bound(Thunk<Val>),100 Bound(Thunk<Val>),
79}101}
80102
81impl Debug for LazyBinding {103impl Debug for MaybeUnbound {
82 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
83 write!(f, "LazyBinding")105 write!(f, "MaybeUnbound")
84 }106 }
85}107}
86impl LazyBinding {108impl MaybeUnbound {
109 /// Attach object context to value, if required
87 pub fn evaluate(110 pub fn evaluate(
88 &self,111 &self,
89 s: State,112 s: State,
90 sup: Option<ObjValue>,113 sup: Option<ObjValue>,
91 this: Option<ObjValue>,114 this: Option<ObjValue>,
92 ) -> Result<Thunk<Val>> {115 ) -> Result<Thunk<Val>> {
93 match self {116 match self {
94 Self::Bindable(v) => v.bind(s, sup, this),117 Self::Unbound(v) => v.bind(s, sup, this),
95 Self::Bound(v) => Ok(v.clone()),118 Self::Bound(v) => Ok(v.clone()),
96 }119 }
97 }120 }
98}121}
99122
100/// During import, this trait will be called to create initial context for file123/// During import, this trait will be called to create initial context for file.
101/// It may initialize global variables, stdlib for example124/// It may initialize global variables, stdlib for example.
102pub trait ContextInitializer {125pub trait ContextInitializer {
126 /// Initialize default file context.
103 fn initialize(&self, state: State, for_file: Source) -> Context;127 fn initialize(&self, state: State, for_file: Source) -> Context;
104128 /// Allows upcasting from abstract to concrete context initializer.
129 /// jrsonnet by itself doesn't use this method, it is allowed for it to panic.
105 fn as_any(&self) -> &dyn Any;130 fn as_any(&self) -> &dyn Any;
106}131}
107132
116 }141 }
117}142}
118143
144/// Dynamically reconfigurable evaluation settings
119pub struct EvaluationSettings {145pub struct EvaluationSettings {
120 /// Limits recursion by limiting the number of stack frames146 /// Limits recursion by limiting the number of stack frames
121 pub max_stack: usize,147 pub max_stack: usize,
401 /// Executes code creating a new stack frame427 /// Executes code creating a new stack frame
402 pub fn push<T>(428 pub fn push<T>(
403 &self,429 &self,
404 e: CallLocation,430 e: CallLocation<'_>,
405 frame_desc: impl FnOnce() -> String,431 frame_desc: impl FnOnce() -> String,
406 f: impl FnOnce() -> Result<T>,432 f: impl FnOnce() -> Result<T>,
407 ) -> Result<T> {433 ) -> Result<T> {
547573
548/// Internals574/// Internals
549impl State {575impl State {
550 // fn data(&self) -> Ref<EvaluationData> {
551 // self.0.data.borrow()
552 // }
553 fn data_mut(&self) -> RefMut<EvaluationData> {576 fn data_mut(&self) -> RefMut<'_, EvaluationData> {
554 self.0.data.borrow_mut()577 self.0.data.borrow_mut()
555 }578 }
556 pub fn settings(&self) -> Ref<EvaluationSettings> {579 pub fn settings(&self) -> Ref<'_, EvaluationSettings> {
557 self.0.settings.borrow()580 self.0.settings.borrow()
558 }581 }
559 pub fn settings_mut(&self) -> RefMut<EvaluationSettings> {582 pub fn settings_mut(&self) -> RefMut<'_, EvaluationSettings> {
560 self.0.settings.borrow_mut()583 self.0.settings.borrow_mut()
561 }584 }
562}585}
623 pub fn resolve(&self, path: impl AsRef<Path>) -> Result<SourcePath> {646 pub fn resolve(&self, path: impl AsRef<Path>) -> Result<SourcePath> {
624 self.import_resolver().resolve(path.as_ref())647 self.import_resolver().resolve(path.as_ref())
625 }648 }
626 pub fn import_resolver(&self) -> Ref<dyn ImportResolver> {649 pub fn import_resolver(&self) -> Ref<'_, dyn ImportResolver> {
627 Ref::map(self.settings(), |s| &*s.import_resolver)650 Ref::map(self.settings(), |s| &*s.import_resolver)
628 }651 }
629 pub fn set_import_resolver(&self, resolver: Box<dyn ImportResolver>) {652 pub fn set_import_resolver(&self, resolver: Box<dyn ImportResolver>) {
630 self.settings_mut().import_resolver = resolver;653 self.settings_mut().import_resolver = resolver;
631 }654 }
632 pub fn context_initializer(&self) -> Ref<dyn ContextInitializer> {655 pub fn context_initializer(&self) -> Ref<'_, dyn ContextInitializer> {
633 Ref::map(self.settings(), |s| &*s.context_initializer)656 Ref::map(self.settings(), |s| &*s.context_initializer)
634 }657 }
635658
640 self.settings_mut().manifest_format = format;663 self.settings_mut().manifest_format = format;
641 }664 }
642665
643 pub fn trace_format(&self) -> Ref<dyn TraceFormat> {666 pub fn trace_format(&self) -> Ref<'_, dyn TraceFormat> {
644 Ref::map(self.settings(), |s| &*s.trace_format)667 Ref::map(self.settings(), |s| &*s.trace_format)
645 }668 }
646 pub fn set_trace_format(&self, format: Box<dyn TraceFormat>) {669 pub fn set_trace_format(&self, format: Box<dyn TraceFormat>) {
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
15 function::CallLocation,15 function::CallLocation,
16 gc::{GcHashMap, GcHashSet, TraceBox},16 gc::{GcHashMap, GcHashSet, TraceBox},
17 operator::evaluate_add_op,17 operator::evaluate_add_op,
18 throw, LazyBinding, Result, State, Thunk, Unbound, Val,18 throw, MaybeUnbound, Result, State, Thunk, Unbound, Val,
19};19};
2020
21#[cfg(not(feature = "exp-preserve-order"))]21#[cfg(not(feature = "exp-preserve-order"))]
100 pub add: bool,100 pub add: bool,
101 pub visibility: Visibility,101 pub visibility: Visibility,
102 original_index: FieldIndex,102 original_index: FieldIndex,
103 pub invoke: LazyBinding,103 pub invoke: MaybeUnbound,
104 pub location: Option<ExprLocation>,104 pub location: Option<ExprLocation>,
105}105}
106106
208 new.insert(key, value);208 new.insert(key, value);
209 Self::new(Some(self), Cc::new(new), Cc::new(Vec::new()))209 Self::new(Some(self), Cc::new(new), Cc::new(Vec::new()))
210 }210 }
211 pub fn extend_field(&mut self, name: IStr) -> ObjMemberBuilder<ExtendBuilder> {211 pub fn extend_field(&mut self, name: IStr) -> ObjMemberBuilder<ExtendBuilder<'_>> {
212 ObjMemberBuilder::new(ExtendBuilder(self), name, FieldIndex::default())212 ObjMemberBuilder::new(ExtendBuilder(self), name, FieldIndex::default())
213 }213 }
214214
239 }239 }
240240
241 /// Run callback for every field found in object241 /// Run callback for every field found in object
242 ///
243 /// Returns true if ended prematurely
242 pub(crate) fn enum_fields(244 pub(crate) fn enum_fields(
243 &self,245 &self,
244 depth: SuperDepth,246 depth: SuperDepth,
500 self.assertions.push(assertion);502 self.assertions.push(assertion);
501 self503 self
502 }504 }
503 pub fn member(&mut self, name: IStr) -> ObjMemberBuilder<ValueBuilder> {505 pub fn member(&mut self, name: IStr) -> ObjMemberBuilder<ValueBuilder<'_>> {
504 let field_index = self.next_field_index;506 let field_index = self.next_field_index;
505 self.next_field_index = self.next_field_index.next();507 self.next_field_index = self.next_field_index.next();
506 ObjMemberBuilder::new(ValueBuilder(self), name, field_index)508 ObjMemberBuilder::new(ValueBuilder(self), name, field_index)
558 self.location = Some(location);560 self.location = Some(location);
559 self561 self
560 }562 }
561 fn build_member(self, binding: LazyBinding) -> (Kind, IStr, ObjMember) {563 fn build_member(self, binding: MaybeUnbound) -> (Kind, IStr, ObjMember) {
562 (564 (
563 self.kind,565 self.kind,
564 self.name,566 self.name,
574}576}
575577
576pub struct ValueBuilder<'v>(&'v mut ObjValueBuilder);578pub struct ValueBuilder<'v>(&'v mut ObjValueBuilder);
577impl<'v> ObjMemberBuilder<ValueBuilder<'v>> {579impl ObjMemberBuilder<ValueBuilder<'_>> {
578 pub fn value(self, s: State, value: Val) -> Result<()> {580 pub fn value(self, s: State, value: Val) -> Result<()> {
579 self.binding(s, LazyBinding::Bound(Thunk::evaluated(value)))581 self.binding(s, MaybeUnbound::Bound(Thunk::evaluated(value)))
580 }582 }
581 pub fn bindable(583 pub fn bindable(
582 self,584 self,
583 s: State,585 s: State,
584 bindable: TraceBox<dyn Unbound<Bound = Thunk<Val>>>,586 bindable: TraceBox<dyn Unbound<Bound = Thunk<Val>>>,
585 ) -> Result<()> {587 ) -> Result<()> {
586 self.binding(s, LazyBinding::Bindable(Cc::new(bindable)))588 self.binding(s, MaybeUnbound::Unbound(Cc::new(bindable)))
587 }589 }
588 pub fn binding(self, s: State, binding: LazyBinding) -> Result<()> {590 pub fn binding(self, s: State, binding: MaybeUnbound) -> Result<()> {
589 let (receiver, name, member) = self.build_member(binding);591 let (receiver, name, member) = self.build_member(binding);
590 let location = member.location.clone();592 let location = member.location.clone();
591 let old = receiver.0.map.insert(name.clone(), member);593 let old = receiver.0.map.insert(name.clone(), member);
601}603}
602604
603pub struct ExtendBuilder<'v>(&'v mut ObjValue);605pub struct ExtendBuilder<'v>(&'v mut ObjValue);
604impl<'v> ObjMemberBuilder<ExtendBuilder<'v>> {606impl ObjMemberBuilder<ExtendBuilder<'_>> {
605 pub fn value(self, value: Val) {607 pub fn value(self, value: Val) {
606 self.binding(LazyBinding::Bound(Thunk::evaluated(value)));608 self.binding(MaybeUnbound::Bound(Thunk::evaluated(value)));
607 }609 }
608 pub fn bindable(self, bindable: TraceBox<dyn Unbound<Bound = Thunk<Val>>>) {610 pub fn bindable(self, bindable: TraceBox<dyn Unbound<Bound = Thunk<Val>>>) {
609 self.binding(LazyBinding::Bindable(Cc::new(bindable)));611 self.binding(MaybeUnbound::Unbound(Cc::new(bindable)));
610 }612 }
611 pub fn binding(self, binding: LazyBinding) {613 pub fn binding(self, binding: MaybeUnbound) {
612 let (receiver, name, member) = self.build_member(binding);614 let (receiver, name, member) = self.build_member(binding);
613 let new = receiver.0.clone();615 let new = receiver.0.clone();
614 *receiver.0 = new.extend_with_raw_member(name, member);616 *receiver.0 = new.extend_with_raw_member(name, member);
modifiedcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth
3636
37type ParseResult<'t, T> = std::result::Result<(T, &'t str), FormatError>;37type ParseResult<'t, T> = std::result::Result<(T, &'t str), FormatError>;
3838
39pub fn try_parse_mapping_key(str: &str) -> ParseResult<&str> {39pub fn try_parse_mapping_key(str: &str) -> ParseResult<'_, &str> {
40 if str.is_empty() {40 if str.is_empty() {
41 return Err(TruncatedFormatCode);41 return Err(TruncatedFormatCode);
42 }42 }
96 pub sign: bool,96 pub sign: bool,
97}97}
9898
99pub fn try_parse_cflags(str: &str) -> ParseResult<CFlags> {99pub fn try_parse_cflags(str: &str) -> ParseResult<'_, CFlags> {
100 if str.is_empty() {100 if str.is_empty() {
101 return Err(TruncatedFormatCode);101 return Err(TruncatedFormatCode);
102 }102 }
125 Star,125 Star,
126 Fixed(usize),126 Fixed(usize),
127}127}
128pub fn try_parse_field_width(str: &str) -> ParseResult<Width> {128pub fn try_parse_field_width(str: &str) -> ParseResult<'_, Width> {
129 if str.is_empty() {129 if str.is_empty() {
130 return Err(TruncatedFormatCode);130 return Err(TruncatedFormatCode);
131 }131 }
146 Ok((Width::Fixed(out), &str[digits..]))146 Ok((Width::Fixed(out), &str[digits..]))
147}147}
148148
149pub fn try_parse_precision(str: &str) -> ParseResult<Option<Width>> {149pub fn try_parse_precision(str: &str) -> ParseResult<'_, Option<Width>> {
150 if str.is_empty() {150 if str.is_empty() {
151 return Err(TruncatedFormatCode);151 return Err(TruncatedFormatCode);
152 }152 }
159}159}
160160
161// Only skips161// Only skips
162pub fn try_parse_length_modifier(str: &str) -> ParseResult<()> {162pub fn try_parse_length_modifier(str: &str) -> ParseResult<'_, ()> {
163 if str.is_empty() {163 if str.is_empty() {
164 return Err(TruncatedFormatCode);164 return Err(TruncatedFormatCode);
165 }165 }
191 caps: bool,191 caps: bool,
192}192}
193193
194pub fn parse_conversion_type(str: &str) -> ParseResult<ConvType> {194pub fn parse_conversion_type(str: &str) -> ParseResult<'_, ConvType> {
195 if str.is_empty() {195 if str.is_empty() {
196 return Err(TruncatedFormatCode);196 return Err(TruncatedFormatCode);
197 }197 }
226 convtype: ConvTypeV,226 convtype: ConvTypeV,
227 caps: bool,227 caps: bool,
228}228}
229pub fn parse_code(str: &str) -> ParseResult<Code> {229pub fn parse_code(str: &str) -> ParseResult<'_, Code<'_>> {
230 if str.is_empty() {230 if str.is_empty() {
231 return Err(TruncatedFormatCode);231 return Err(TruncatedFormatCode);
232 }232 }
255 String(&'s str),255 String(&'s str),
256 Code(Code<'s>),256 Code(Code<'s>),
257}257}
258pub fn parse_codes(mut str: &str) -> Result<Vec<Element>> {258pub fn parse_codes(mut str: &str) -> Result<Vec<Element<'_>>> {
259 let mut bytes = str.as_bytes();259 let mut bytes = str.as_bytes();
260 let mut out = vec![];260 let mut out = vec![];
261 let mut offset = 0;261 let mut offset = 0;
475 s: State,475 s: State,
476 out: &mut String,476 out: &mut String,
477 value: &Val,477 value: &Val,
478 code: &Code,478 code: &Code<'_>,
479 width: usize,479 width: usize,
480 precision: Option<usize>,480 precision: Option<usize>,
481) -> Result<()> {481) -> Result<()> {
modifiedcrates/jrsonnet-evaluator/src/stdlib/manifest.rsdiffbeforeafterboth
116 || {116 || {
117 let value = obj.get(s.clone(), field.clone())?.unwrap();117 let value = obj.get(s.clone(), field.clone())?.unwrap();
118 manifest_json_ex_buf(s.clone(), &value, buf, cur_padding, options)?;118 manifest_json_ex_buf(s.clone(), &value, buf, cur_padding, options)?;
119 Ok(Val::Null)119 Ok(())
120 },120 },
121 )?;121 )?;
122 }122 }
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
186 }186 }
187}187}
188188
189/// Represents a Jsonnet array value.
189#[derive(Debug, Clone, Trace)]190#[derive(Debug, Clone, Trace)]
190// may contrain other ArrValue191// may contrain other ArrValue
191#[trace(tracking(force))]192#[trace(tracking(force))]
192pub enum ArrValue {193pub enum ArrValue {
194 /// Layout optimized byte array.
193 Bytes(#[trace(skip)] IBytes),195 Bytes(#[trace(skip)] IBytes),
196 /// Every element is lazy evaluated.
194 Lazy(Cc<Vec<Thunk<Val>>>),197 Lazy(Cc<Vec<Thunk<Val>>>),
198 /// Every field is already evaluated.
195 Eager(Cc<Vec<Val>>),199 Eager(Cc<Vec<Val>>),
200 /// Concatenation of two arrays of any kind.
196 Extended(Box<(Self, Self)>),201 Extended(Box<(Self, Self)>),
202 /// Represents a integer array in form `[start, start + 1, ... end - 1, end]`.
203 /// This kind of arrays is generated by `std.range(start, end)` call, and used for loops.
197 Range(i32, i32),204 Range(i32, i32),
205 /// Sliced array view.
198 Slice(Box<Slice>),206 Slice(Box<Slice>),
207 /// Reversed array view.
208 /// Returned by `std.reverse(other)` call
199 Reversed(Box<Self>),209 Reversed(Box<Self>),
200}210}
201211
237 }))247 }))
238 }248 }
239249
250 /// Array length.
240 pub fn len(&self) -> usize {251 pub fn len(&self) -> usize {
241 match self {252 match self {
242 Self::Bytes(i) => i.len(),253 Self::Bytes(i) => i.len(),
249 }260 }
250 }261 }
251262
263 /// Is array contains no elements?
252 pub fn is_empty(&self) -> bool {264 pub fn is_empty(&self) -> bool {
253 self.len() == 0265 self.len() == 0
254 }266 }
255267
268 /// Get array element by index, evaluating it, if it is lazy.
269 ///
270 /// Returns `None` on out-of-bounds condition.
256 pub fn get(&self, s: State, index: usize) -> Result<Option<Val>> {271 pub fn get(&self, s: State, index: usize) -> Result<Option<Val>> {
257 match self {272 match self {
258 Self::Bytes(i) => i273 Self::Bytes(i) => i
297 }312 }
298 }313 }
299314
315 /// Get array element by index, without evaluation.
316 ///
317 /// Returns `None` on out-of-bounds condition.
300 pub fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {318 pub fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {
301 match self {319 match self {
302 Self::Bytes(i) => i320 Self::Bytes(i) => i
337 }355 }
338 }356 }
339357
358 /// Evaluate all array elements, returning new array.
340 pub fn evaluated(&self, s: State) -> Result<Cc<Vec<Val>>> {359 pub fn evaluated(&self, s: State) -> Result<Cc<Vec<Val>>> {
341 Ok(match self {360 Ok(match self {
342 Self::Bytes(i) => {361 Self::Bytes(i) => {
389 })408 })
390 }409 }
391410
411 /// Iterate over elements, evaluating them.
392 pub fn iter(&self, s: State) -> impl DoubleEndedIterator<Item = Result<Val>> + '_ {412 pub fn iter(&self, s: State) -> impl DoubleEndedIterator<Item = Result<Val>> + '_ {
393 (0..self.len()).map(move |idx| match self {413 (0..self.len()).map(move |idx| match self {
394 Self::Bytes(b) => Ok(Val::Num(f64::from(b[idx]))),414 Self::Bytes(b) => Ok(Val::Num(f64::from(b[idx]))),
400 })420 })
401 }421 }
402422
423 /// Iterate over elements, returning lazy values.
403 pub fn iter_lazy(&self) -> impl DoubleEndedIterator<Item = Thunk<Val>> + '_ {424 pub fn iter_lazy(&self) -> impl DoubleEndedIterator<Item = Thunk<Val>> + '_ {
404 (0..self.len()).map(move |idx| match self {425 (0..self.len()).map(move |idx| match self {
405 Self::Bytes(b) => Thunk::evaluated(Val::Num(f64::from(b[idx]))),426 Self::Bytes(b) => Thunk::evaluated(Val::Num(f64::from(b[idx]))),
411 })432 })
412 }433 }
413434
435 /// Return a reversed view on current array.
414 #[must_use]436 #[must_use]
415 pub fn reversed(self) -> Self {437 pub fn reversed(self) -> Self {
416 Self::Reversed(Box::new(self))438 Self::Reversed(Box::new(self))
417 }439 }
418440
441 /// Return a new array, produced by passing every element of current array to specified callback function.
419 pub fn map(self, s: State, mapper: impl Fn(Val) -> Result<Val>) -> Result<Self> {442 pub fn map(self, s: State, mapper: impl Fn(Val) -> Result<Val>) -> Result<Self> {
420 let mut out = Vec::with_capacity(self.len());443 let mut out = Vec::with_capacity(self.len());
421444
426 Ok(Self::Eager(Cc::new(out)))449 Ok(Self::Eager(Cc::new(out)))
427 }450 }
428451
452 /// Return a new array, produced from current array by removing every value, for which specified callback function returns false.
429 pub fn filter(self, s: State, filter: impl Fn(&Val) -> Result<bool>) -> Result<Self> {453 pub fn filter(self, s: State, filter: impl Fn(&Val) -> Result<bool>) -> Result<Self> {
430 let mut out = Vec::with_capacity(self.len());454 let mut out = Vec::with_capacity(self.len());
431455
460 }484 }
461}485}
462486
487/// Represents a Jsonnet value, which can be spliced or indexed (string or array).
463#[allow(clippy::module_name_repetitions)]488#[allow(clippy::module_name_repetitions)]
464pub enum IndexableVal {489pub enum IndexableVal {
490 /// String.
465 Str(IStr),491 Str(IStr),
492 /// Array.
466 Arr(ArrValue),493 Arr(ArrValue),
467}494}
468impl IndexableVal {495impl IndexableVal {
496 /// Slice the value.
497 ///
498 /// # Implementation
499 ///
500 /// For strings, will create a copy of specified interval.
501 ///
502 /// For arrays, nothing will be copied on this call, instead [`ArrValue::Slice`] view will be returned.
469 pub fn slice(503 pub fn slice(
470 self,504 self,
471 index: Option<BoundedUsize<0, { i32::MAX as usize }>>,505 index: Option<BoundedUsize<0, { i32::MAX as usize }>>,
511 }545 }
512}546}
513547
548/// Represents any valid Jsonnet value.
514#[derive(Debug, Clone, Trace)]549#[derive(Debug, Clone, Trace)]
515pub enum Val {550pub enum Val {
551 /// Represents a Jsonnet boolean.
516 Bool(bool),552 Bool(bool),
553 /// Represents a Jsonnet null value.
517 Null,554 Null,
555 /// Represents a Jsonnet string.
518 Str(IStr),556 Str(IStr),
557 /// Represents a Jsonnet number.
558 /// Should be finite, and not NaN
559 /// This restriction isn't enforced by enum, as enum field can't be marked as private
519 Num(f64),560 Num(f64),
561 /// Represents a Jsonnet array.
520 Arr(ArrValue),562 Arr(ArrValue),
563 /// Represents a Jsonnet object.
521 Obj(ObjValue),564 Obj(ObjValue),
565 /// Represents a Jsonnet function.
522 Func(FuncVal),566 Func(FuncVal),
523}567}
524568
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
52 builder.with_super(eval);52 builder.with_super(eval);
5353
54 for (name, builtin) in [54 for (name, builtin) in [
55 ("length".into(), builtin_length::INST),55 ("length", builtin_length::INST),
56 // Types56 // Types
57 ("type".into(), builtin_type::INST),57 ("type", builtin_type::INST),
58 ("isString".into(), builtin_is_string::INST),58 ("isString", builtin_is_string::INST),
59 ("isNumber".into(), builtin_is_number::INST),59 ("isNumber", builtin_is_number::INST),
60 ("isBoolean".into(), builtin_is_boolean::INST),60 ("isBoolean", builtin_is_boolean::INST),
61 ("isObject".into(), builtin_is_object::INST),61 ("isObject", builtin_is_object::INST),
62 ("isArray".into(), builtin_is_array::INST),62 ("isArray", builtin_is_array::INST),
63 ("isFunction".into(), builtin_is_function::INST),63 ("isFunction", builtin_is_function::INST),
64 // Arrays64 // Arrays
65 ("makeArray".into(), builtin_make_array::INST),65 ("makeArray", builtin_make_array::INST),
66 ("slice".into(), builtin_slice::INST),66 ("slice", builtin_slice::INST),
67 ("map".into(), builtin_map::INST),67 ("map", builtin_map::INST),
68 ("flatMap".into(), builtin_flatmap::INST),68 ("flatMap", builtin_flatmap::INST),
69 ("filter".into(), builtin_filter::INST),69 ("filter", builtin_filter::INST),
70 ("foldl".into(), builtin_foldl::INST),70 ("foldl", builtin_foldl::INST),
71 ("foldr".into(), builtin_foldr::INST),71 ("foldr", builtin_foldr::INST),
72 ("range".into(), builtin_range::INST),72 ("range", builtin_range::INST),
73 ("join".into(), builtin_join::INST),73 ("join", builtin_join::INST),
74 ("reverse".into(), builtin_reverse::INST),74 ("reverse", builtin_reverse::INST),
75 ("any".into(), builtin_any::INST),75 ("any", builtin_any::INST),
76 ("all".into(), builtin_all::INST),76 ("all", builtin_all::INST),
77 ("member".into(), builtin_member::INST),77 ("member", builtin_member::INST),
78 ("count".into(), builtin_count::INST),78 ("count", builtin_count::INST),
79 // Math79 // Math
80 ("modulo".into(), builtin_modulo::INST),80 ("modulo", builtin_modulo::INST),
81 ("floor".into(), builtin_floor::INST),81 ("floor", builtin_floor::INST),
82 ("ceil".into(), builtin_ceil::INST),82 ("ceil", builtin_ceil::INST),
83 ("log".into(), builtin_log::INST),83 ("log", builtin_log::INST),
84 ("pow".into(), builtin_pow::INST),84 ("pow", builtin_pow::INST),
85 ("sqrt".into(), builtin_sqrt::INST),85 ("sqrt", builtin_sqrt::INST),
86 ("sin".into(), builtin_sin::INST),86 ("sin", builtin_sin::INST),
87 ("cos".into(), builtin_cos::INST),87 ("cos", builtin_cos::INST),
88 ("tan".into(), builtin_tan::INST),88 ("tan", builtin_tan::INST),
89 ("asin".into(), builtin_asin::INST),89 ("asin", builtin_asin::INST),
90 ("acos".into(), builtin_acos::INST),90 ("acos", builtin_acos::INST),
91 ("atan".into(), builtin_atan::INST),91 ("atan", builtin_atan::INST),
92 ("exp".into(), builtin_exp::INST),92 ("exp", builtin_exp::INST),
93 ("mantissa".into(), builtin_mantissa::INST),93 ("mantissa", builtin_mantissa::INST),
94 ("exponent".into(), builtin_exponent::INST),94 ("exponent", builtin_exponent::INST),
95 // Operator95 // Operator
96 ("mod".into(), builtin_mod::INST),96 ("mod", builtin_mod::INST),
97 ("primitiveEquals".into(), builtin_primitive_equals::INST),97 ("primitiveEquals", builtin_primitive_equals::INST),
98 ("equals".into(), builtin_equals::INST),98 ("equals", builtin_equals::INST),
99 ("format".into(), builtin_format::INST),99 ("format", builtin_format::INST),
100 // Sort100 // Sort
101 ("sort".into(), builtin_sort::INST),101 ("sort", builtin_sort::INST),
102 // Hash102 // Hash
103 ("md5".into(), builtin_md5::INST),103 ("md5", builtin_md5::INST),
104 // Encoding104 // Encoding
105 ("encodeUTF8".into(), builtin_encode_utf8::INST),105 ("encodeUTF8", builtin_encode_utf8::INST),
106 ("decodeUTF8".into(), builtin_decode_utf8::INST),106 ("decodeUTF8", builtin_decode_utf8::INST),
107 ("base64".into(), builtin_base64::INST),107 ("base64", builtin_base64::INST),
108 ("base64Decode".into(), builtin_base64_decode::INST),108 ("base64Decode", builtin_base64_decode::INST),
109 (109 ("base64DecodeBytes", builtin_base64_decode_bytes::INST),
110 "base64DecodeBytes".into(),
111 builtin_base64_decode_bytes::INST,
112 ),
113 // Objects110 // Objects
114 ("objectFieldsEx".into(), builtin_object_fields_ex::INST),111 ("objectFieldsEx", builtin_object_fields_ex::INST),
115 ("objectHasEx".into(), builtin_object_has_ex::INST),112 ("objectHasEx", builtin_object_has_ex::INST),
116 // Manifest113 // Manifest
117 ("escapeStringJson".into(), builtin_escape_string_json::INST),114 ("escapeStringJson", builtin_escape_string_json::INST),
118 ("manifestJsonEx".into(), builtin_manifest_json_ex::INST),115 ("manifestJsonEx", builtin_manifest_json_ex::INST),
119 ("manifestYamlDoc".into(), builtin_manifest_yaml_doc::INST),116 ("manifestYamlDoc", builtin_manifest_yaml_doc::INST),
120 // Parsing117 // Parsing
121 ("parseJson".into(), builtin_parse_json::INST),118 ("parseJson", builtin_parse_json::INST),
122 ("parseYaml".into(), builtin_parse_yaml::INST),119 ("parseYaml", builtin_parse_yaml::INST),
123 // Misc120 // Misc
124 ("codepoint".into(), builtin_codepoint::INST),121 ("codepoint", builtin_codepoint::INST),
125 ("substr".into(), builtin_substr::INST),122 ("substr", builtin_substr::INST),
126 ("char".into(), builtin_char::INST),123 ("char", builtin_char::INST),
127 ("strReplace".into(), builtin_str_replace::INST),124 ("strReplace", builtin_str_replace::INST),
128 ("splitLimit".into(), builtin_splitlimit::INST),125 ("splitLimit", builtin_splitlimit::INST),
129 ("asciiUpper".into(), builtin_ascii_upper::INST),126 ("asciiUpper", builtin_ascii_upper::INST),
130 ("asciiLower".into(), builtin_ascii_lower::INST),127 ("asciiLower", builtin_ascii_lower::INST),
131 ("findSubstr".into(), builtin_find_substr::INST),128 ("findSubstr", builtin_find_substr::INST),
132 ("startsWith".into(), builtin_starts_with::INST),129 ("startsWith", builtin_starts_with::INST),
133 ("endsWith".into(), builtin_ends_with::INST),130 ("endsWith", builtin_ends_with::INST),
134 ]131 ]
135 .iter()132 .iter()
136 .cloned()133 .cloned()
137 {134 {
138 builder135 builder
139 .member(name)136 .member(name.into())
140 .hide()137 .hide()
141 .value(s.clone(), Val::Func(FuncVal::StaticBuiltin(builtin)))138 .value(s.clone(), Val::Func(FuncVal::StaticBuiltin(builtin)))
142 .expect("no conflict");139 .expect("no conflict");
modifiedtests/src/lib.rsdiffbeforeafterboth
11//! See tests/, suite/ and golden/ directories for tests
22