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

difftreelog

feat std.parseYaml intrinsic

Yaroslav Bolyukin2021-11-27parent: #7c0b097.patch.diff
in: master

6 files changed

modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
7edition = "2018"7edition = "2018"
88
9[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 run
12serialized-stdlib = ["serde", "bincode", "jrsonnet-parser/deserialize"]12serialized-stdlib = ["bincode", "jrsonnet-parser/deserialize"]
13# Allow to convert Val into serde_json::Value and backwards
14serde-json = ["serde", "serde_json"]
15# Rustc-like trace visualization13# Rustc-like trace visualization
16explaining-traces = ["annotate-snippets"]14explaining-traces = ["annotate-snippets"]
17# Allows library authors to throw custom errors15# Allows library authors to throw custom errors
34thiserror = "1.0"32thiserror = "1.0"
35gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }33gcmodule = { git = "https://github.com/CertainLach/gcmodule", branch = "jrsonnet" }
34
35serde = "1.0"
36serde_json = "1.0"
37serde_yaml = { git = "https://github.com/CertainLach/serde-yaml", branch = "feature/old-octals-quirk" }
3638
37[dependencies.anyhow]39[dependencies.anyhow]
38version = "1.0"40version = "1.0"
39optional = true41optional = true
4042
41# Serialized stdlib43# Serialized stdlib
42[dependencies.serde]
43version = "1.0"
44optional = true
45[dependencies.bincode]44[dependencies.bincode]
46version = "1.3.1"45version = "1.3.1"
47optional = true46optional = true
48
49# Serde json
50[dependencies.serde_json]
51version = "1.0"
52optional = true
5347
54# Explaining traces48# Explaining traces
55[dependencies.annotate-snippets]49[dependencies.annotate-snippets]
modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
4 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};
1517
16pub 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}
208211
209fn 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}
220
221fn 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}
218242
modifiedcrates/jrsonnet-evaluator/src/integrations/mod.rsdiffbeforeafterboth
1#[cfg(feature = "serde-json")]
2pub mod serde;1pub mod serde;
32
modifiedcrates/jrsonnet-evaluator/src/integrations/serde.rsdiffbeforeafterboth
15 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}
4143
42impl 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}
6671
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
98 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 true
103 } else {103 } else {
104 false104 false
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
23 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),
2627
27 log:: $intrinsic(log),28 log:: $intrinsic(log),
28 pow:: $intrinsic(pow),29 pow:: $intrinsic(pow),