difftreelog
feat std.parseYaml intrinsic
in: master
6 files changed
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth7edition = "2018"7edition = "2018"889[features]9[features]10default = ["serialized-stdlib", "explaining-traces", "serde-json"]10default = ["serialized-stdlib", "explaining-traces"]11# Serializes standard library AST instead of parsing them every run11# Serializes standard library AST instead of parsing them every run12serialized-stdlib = ["serde", "bincode", "jrsonnet-parser/deserialize"]12serialized-stdlib = ["bincode", "jrsonnet-parser/deserialize"]13# Allow to convert Val into serde_json::Value and backwards14serde-json = ["serde", "serde_json"]15# Rustc-like trace visualization13# Rustc-like trace visualization16explaining-traces = ["annotate-snippets"]14explaining-traces = ["annotate-snippets"]17# Allows library authors to throw custom errors15# Allows library authors to throw custom errors34thiserror = "1.0"32thiserror = "1.0"35gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }33gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }3435serde = "1.0"36serde_json = "1.0"37serde_yaml = { git = "https://github.com/CertainLach/serde-yaml", branch = "feature/old-octals-quirk" }363837[dependencies.anyhow]39[dependencies.anyhow]38version = "1.0"40version = "1.0"39optional = true41optional = true404241# Serialized stdlib43# Serialized stdlib42[dependencies.serde]43version = "1.0"44optional = true45[dependencies.bincode]44[dependencies.bincode]46version = "1.3.1"45version = "1.3.1"47optional = true46optional = true4849# Serde json50[dependencies.serde_json]51version = "1.0"52optional = true534754# Explaining traces48# Explaining traces55[dependencies.annotate-snippets]49[dependencies.annotate-snippets]crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth4 error::{Error::*, Result},4 error::{Error::*, Result},5 operator::evaluate_mod_op,5 operator::evaluate_mod_op,6 parse_args, primitive_equals, push_frame, throw, with_state, ArrValue, Context,6 parse_args, primitive_equals, push_frame, throw, with_state, ArrValue, Context, FuncVal,7 EvaluationState, FuncVal, IndexableVal, LazyVal, Val,7 IndexableVal, LazyVal, Val,8};8};9use format::{format_arr, format_obj};9use format::{format_arr, format_obj};10use gcmodule::Cc;10use gcmodule::Cc;11use jrsonnet_interner::IStr;11use jrsonnet_interner::IStr;12use jrsonnet_parser::{ArgsDesc, ExprLocation};12use jrsonnet_parser::{ArgsDesc, ExprLocation};13use jrsonnet_types::ty;13use jrsonnet_types::ty;14use serde::Deserialize;15use serde_yaml::DeserializingQuirks;14use std::{collections::HashMap, path::PathBuf, rc::Rc};16use std::{collections::HashMap, convert::TryFrom, path::PathBuf, rc::Rc};151716pub mod stdlib;18pub mod stdlib;17pub use stdlib::*;19pub use stdlib::*;128 ("strReplace".into(), builtin_str_replace),130 ("strReplace".into(), builtin_str_replace),129 ("splitLimit".into(), builtin_splitlimit),131 ("splitLimit".into(), builtin_splitlimit),130 ("parseJson".into(), builtin_parse_json),132 ("parseJson".into(), builtin_parse_json),133 ("parseYaml".into(), builtin_parse_yaml),131 ("asciiUpper".into(), builtin_ascii_upper),134 ("asciiUpper".into(), builtin_ascii_upper),132 ("asciiLower".into(), builtin_ascii_lower),135 ("asciiLower".into(), builtin_ascii_lower),133 ("member".into(), builtin_member),136 ("member".into(), builtin_member),206 })209 })207}210}208211209fn builtin_parse_json(context: Context, _loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {212fn builtin_parse_json(context: Context, _loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {213 parse_args!(context, "parseJson", args, 1, [214 0, s: ty!(string) => Val::Str;215 ], {216 let value: serde_json::Value = serde_json::from_str(&s).map_err(|e| RuntimeError(format!("failed to parse json: {}", e).into()))?;217 Ok(Val::try_from(&value)?)218 })219}220221fn builtin_parse_yaml(context: Context, _loc: &ExprLocation, args: &ArgsDesc) -> Result<Val> {210 parse_args!(context, "parseJson", args, 1, [222 parse_args!(context, "parseYaml", args, 1, [211 0, s: ty!(string) => Val::Str;223 0, s: ty!(string) => Val::Str;212 ], {224 ], {213 let state = EvaluationState::default();225 let value = serde_yaml::Deserializer::from_str_with_quirks(&s, DeserializingQuirks { old_octals: true });214 let path = PathBuf::from("std.parseJson").into();226 let mut out = vec![];227 for item in value {228 let value = serde_json::Value::deserialize(item)229 .map_err(|e| RuntimeError(format!("failed to parse yaml: {}", e).into()))?;230 let val = Val::try_from(&value)?;231 out.push(val);232 }233 if out.is_empty() {234 Ok(Val::Null)215 state.evaluate_snippet_raw(path ,s)235 } else if out.len() == 1 {236 Ok(out.into_iter().next().unwrap())237 } else {238 Ok(Val::Arr(out.into()))239 }216 })240 })217}241}218242crates/jrsonnet-evaluator/src/integrations/mod.rsdiffbeforeafterboth1#[cfg(feature = "serde-json")]2pub mod serde;1pub mod serde;32crates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth15 Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {15 Val::Num(n) => Self::Number(if n.fract() <= f64::EPSILON {16 (*n as i64).into()16 (*n as i64).into()17 } else {17 } else {18 Number::from_f64(*n).expect("to json number")18 Number::from_f64(*n).expect("jsonnet numbers can't be infinite or NaN")19 }),19 }),20 Val::Arr(a) => {20 Val::Arr(a) => {21 let mut out = Vec::with_capacity(a.len());21 let mut out = Vec::with_capacity(a.len());29 for key in o.fields() {29 for key in o.fields() {30 out.insert(30 out.insert(31 (&key as &str).into(),31 (&key as &str).into(),32 (&o.get(key)?.expect("field exists")).try_into()?,32 (&o.get(key)?33 .expect("key is present in fields, so value should exist"))34 .try_into()?,33 );35 );34 }36 }39 }41 }40}42}414342impl From<&Value> for Val {44impl TryFrom<&Value> for Val {45 type Error = LocError;43 fn from(v: &Value) -> Self {46 fn try_from(v: &Value) -> Result<Self> {44 match v {47 Ok(match v {45 Value::Null => Self::Null,48 Value::Null => Self::Null,46 Value::Bool(v) => Self::Bool(*v),49 Value::Bool(v) => Self::Bool(*v),47 Value::Number(n) => Self::Num(n.as_f64().expect("as f64")),50 Value::Number(n) => Self::Num(n.as_f64().ok_or_else(|| {51 RuntimeError(format!("json number can't be represented as jsonnet: {}", n).into())52 })?),48 Value::String(s) => Self::Str((s as &str).into()),53 Value::String(s) => Self::Str((s as &str).into()),49 Value::Array(a) => {54 Value::Array(a) => {50 let mut out: Vec<Self> = Vec::with_capacity(a.len());55 let mut out: Vec<Self> = Vec::with_capacity(a.len());51 for v in a {56 for v in a {52 out.push(v.into());57 out.push(v.try_into()?);53 }58 }54 Self::Arr(out.into())59 Self::Arr(out.into())55 }60 }56 Value::Object(o) => {61 Value::Object(o) => {57 let mut builder = ObjValueBuilder::with_capacity(o.len());62 let mut builder = ObjValueBuilder::with_capacity(o.len());58 for (k, v) in o {63 for (k, v) in o {59 builder.member((k as &str).into()).value(v.into());64 builder.member((k as &str).into()).value(v.try_into()?);60 }65 }61 Self::Obj(builder.build())66 Self::Obj(builder.build())62 }67 }63 }68 })64 }69 }65}70}6671crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth98 let mut n = self.resolver.resolve(path);98 let mut n = self.resolver.resolve(path);99 let mut offset = error.location.offset;99 let mut offset = error.location.offset;100 let is_eof = if offset >= source_code.len() {100 let is_eof = if offset >= source_code.len() {101 offset = source_code.len() - 1;101 offset = source_code.len().saturating_sub(1);102 true102 true103 } else {103 } else {104 false104 falsecrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth23 trace:: $intrinsic(trace),23 trace:: $intrinsic(trace),24 id:: $intrinsic(id),24 id:: $intrinsic(id),25 parseJson:: $intrinsic(parseJson),25 parseJson:: $intrinsic(parseJson),26 parseYaml:: $intrinsic(parseYaml),262727 log:: $intrinsic(log),28 log:: $intrinsic(log),28 pow:: $intrinsic(pow),29 pow:: $intrinsic(pow),