git.delta.rocks / jrsonnet / refs/commits / 1feb056f19c3

difftreelog

feat yaml stream output

Lach2020-08-22parent: #ce6eeac.patch.diff
in: master

5 files changed

modifiedbindings/jsonnet/src/lib.rsdiffbeforeafterboth
--- a/bindings/jsonnet/src/lib.rs
+++ b/bindings/jsonnet/src/lib.rs
@@ -54,7 +54,7 @@
 #[no_mangle]
 pub extern "C" fn jsonnet_string_output(vm: &EvaluationState, v: c_int) {
 	match v {
-		1 => vm.set_manifest_format(ManifestFormat::None),
+		1 => vm.set_manifest_format(ManifestFormat::String),
 		0 => vm.set_manifest_format(ManifestFormat::Json(4)),
 		_ => panic!("incorrect output format"),
 	}
modifiedcrates/jrsonnet-cli/src/manifest.rsdiffbeforeafterboth
55
6pub enum ManifestFormatName {6pub enum ManifestFormatName {
7 /// Expect string as output, and write them directly7 /// Expect string as output, and write them directly
8 None,8 String,
9 Json,9 Json,
10 Yaml,10 Yaml,
11}11}
14 type Err = &'static str;14 type Err = &'static str;
15 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {15 fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
16 Ok(match s {16 Ok(match s {
17 "none" => ManifestFormatName::None,17 "string" => ManifestFormatName::String,
18 "json" => ManifestFormatName::Json,18 "json" => ManifestFormatName::Json,
19 "yaml" => ManifestFormatName::Yaml,19 "yaml" => ManifestFormatName::Yaml,
20 _ => return Err("no such format"),20 _ => return Err("no such format"),
27// #[clap(group = clap::ArgGroup::new("output_format"), help_heading = "MANIFESTIFICATION OUTPUT")]27// #[clap(group = clap::ArgGroup::new("output_format"), help_heading = "MANIFESTIFICATION OUTPUT")]
28pub struct ManifestOpts {28pub struct ManifestOpts {
29 /// Output format, wraps resulting value to corresponding std.manifest call.29 /// Output format, wraps resulting value to corresponding std.manifest call.
30 /// If none - then jsonnet file is expected to return plain string value, otherwise30 /// If string - then jsonnet file is expected to return plain string value, otherwise
31 /// output will be serialized to specified format31 /// output will be serialized to specified format
32 #[clap(long, short = 'f', default_value = "json", possible_values = &["none", "json", "yaml"]/*, group = "output_format"*/)]32 #[clap(long, short = 'f', default_value = "json", possible_values = &["string", "json", "yaml"]/*, group = "output_format"*/)]
33 format: ManifestFormatName,33 format: ManifestFormatName,
34 /// Expect string as output, and write them directly.34 /// Expect string as output, and write them directly.
35 /// Shortcut for --format=none, and can't be set with format together35 /// Shortcut for --format=string, and can't be set with format together
36 #[clap(long, short = 'S'/*, group = "output_format"*/)]36 #[clap(long, short = 'S'/*, group = "output_format"*/)]
37 string: bool,37 string: bool,
38 /// Write output as YAML stream, can be used with --format json/yaml
39 #[clap(long, short = 'y')]
40 yaml_stream: bool,
38 /// Numbed of spaces to pad output manifest with.41 /// Numbed of spaces to pad output manifest with.
39 /// 0 for hard tabs, -1 for single line output42 /// 0 for hard tabs, -1 for single line output
40 #[clap(long, default_value = "3")]43 #[clap(long, default_value = "3")]
43impl ConfigureState for ManifestOpts {46impl ConfigureState for ManifestOpts {
44 fn configure(&self, state: &EvaluationState) -> Result<()> {47 fn configure(&self, state: &EvaluationState) -> Result<()> {
45 if self.string {48 if self.string {
46 state.set_manifest_format(ManifestFormat::None);49 state.set_manifest_format(ManifestFormat::String);
47 } else {50 } else {
48 match self.format {51 match self.format {
49 ManifestFormatName::None => state.set_manifest_format(ManifestFormat::None),52 ManifestFormatName::String => state.set_manifest_format(ManifestFormat::String),
50 ManifestFormatName::Json => {53 ManifestFormatName::Json => {
51 state.set_manifest_format(ManifestFormat::Json(self.line_padding))54 state.set_manifest_format(ManifestFormat::Json(self.line_padding))
52 }55 }
55 }58 }
56 }59 }
57 }60 }
61 if self.yaml_stream {
62 state.set_manifest_format(ManifestFormat::YamlStream(Box::new(
63 state.manifest_format(),
64 )))
65 }
58 Ok(())66 Ok(())
59 }67 }
60}68}
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -58,6 +58,11 @@
 	DivisionByZero,
 
 	StringManifestOutputIsNotAString,
+	StreamManifestOutputIsNotAArray,
+	MultiManifestOutputIsNotAObject,
+
+	StreamManifestOutputCannotBeRecursed,
+	StreamManifestCannotNestString,
 
 	ImportCallbackError(String),
 	InvalidUnicodeCodepointGot(u32),
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -53,13 +53,6 @@
 	}
 }
 
-#[derive(Clone)]
-pub enum ManifestFormat {
-	Yaml(usize),
-	Json(usize),
-	None,
-}
-
 pub struct EvaluationSettings {
 	/// Limits recursion by limiting stack frames
 	pub max_stack: usize,
@@ -321,16 +314,7 @@
 	}
 
 	pub fn manifest(&self, val: Val) -> Result<Rc<str>> {
-		self.run_in_state(|| {
-			Ok(match self.manifest_format() {
-				ManifestFormat::Yaml(padding) => val.into_yaml(padding)?,
-				ManifestFormat::Json(padding) => val.into_json(padding)?,
-				ManifestFormat::None => match val {
-					Val::Str(s) => s,
-					_ => throw!(StringManifestOutputIsNotAString),
-				},
-			})
-		})
+		self.run_in_state(|| val.manifest(&self.manifest_format()))
 	}
 
 	/// If passed value is function - call with set TLA
@@ -521,7 +505,7 @@
 				evaluator
 					.evaluate_snippet_raw(Rc::new(PathBuf::from("raw.jsonnet")), $str.into())
 					.unwrap()
-					.into_json(0)
+					.to_json(0)
 					.unwrap()
 					.replace("\n", "")
 				})
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -131,6 +131,14 @@
 	}
 }
 
+#[derive(Clone)]
+pub enum ManifestFormat {
+	YamlStream(Box<ManifestFormat>),
+	Yaml(usize),
+	Json(usize),
+	String,
+}
+
 #[derive(Debug, Clone)]
 pub enum Val {
 	Bool(bool),
@@ -221,10 +229,46 @@
 		})
 	}
 
+
+	pub fn manifest(&self, ty: &ManifestFormat) -> Result<Rc<str>> {
+		Ok(match ty {
+			ManifestFormat::YamlStream(format) => {
+				let arr = match self {
+					Val::Arr(a) => a,
+					_ => throw!(StreamManifestOutputIsNotAArray),
+				};
+				let mut out = String::new();
+
+				match format as &ManifestFormat {
+					ManifestFormat::YamlStream(_) => throw!(StreamManifestOutputCannotBeRecursed),
+					ManifestFormat::String => throw!(StreamManifestCannotNestString),
+					_ => {}
+				};
+
+				if !arr.is_empty() {
+					for v in arr.iter() {
+						out.push_str("---\n");
+						out.push_str(&v.manifest(format)?);
+						out.push_str("\n");
+					}
+					out.push_str("...");
+				}
+
+				out.into()
+			}
+			ManifestFormat::Yaml(padding) => self.to_yaml(*padding)?,
+			ManifestFormat::Json(padding) => self.to_json(*padding)?,
+			ManifestFormat::String => match self {
+				Val::Str(s) => s.clone(),
+				_ => throw!(StringManifestOutputIsNotAString),
+			},
+		})
+	}
+
 	/// For manifestification
-	pub fn into_json(self, padding: usize) -> Result<Rc<str>> {
+	pub fn to_json(&self, padding: usize) -> Result<Rc<str>> {
 		manifest_json_ex(
-			&self,
+			self,
 			&ManifestJsonOptions {
 				padding: &" ".repeat(padding),
 				mtype: if padding == 0 {
@@ -239,7 +283,7 @@
 
 	/// Calls std.manifestJson
 	#[cfg(feature = "faster")]
-	pub fn into_std_json(self, padding: usize) -> Result<Rc<str>> {
+	pub fn to_std_json(&self, padding: usize) -> Result<Rc<str>> {
 		manifest_json_ex(
 			&self,
 			&ManifestJsonOptions {
@@ -252,11 +296,11 @@
 
 	/// Calls std.manifestJson
 	#[cfg(not(feature = "faster"))]
-	pub fn into_std_json(self, padding: usize) -> Result<Rc<str>> {
+	pub fn to_std_json(&self, padding: usize) -> Result<Rc<str>> {
 		with_state(|s| {
 			let ctx = s
 				.create_default_context()?
-				.with_var("__tmp__to_json__".into(), self)?;
+				.with_var("__tmp__to_json__".into(), self.clone())?;
 			Ok(evaluate(
 				ctx,
 				&el!(Expr::Apply(
@@ -274,11 +318,11 @@
 			.try_cast_str("to json")?)
 		})
 	}
-	pub fn into_yaml(self, padding: usize) -> Result<Rc<str>> {
+	pub fn to_yaml(&self, padding: usize) -> Result<Rc<str>> {
 		with_state(|s| {
 			let ctx = s
 				.create_default_context()?
-				.with_var("__tmp__to_json__".into(), self);
+				.with_var("__tmp__to_json__".into(), self.clone());
 			Ok(evaluate(
 				ctx,
 				&el!(Expr::Apply(