git.delta.rocks / jrsonnet / refs/commits / 44f6e2c9e550

difftreelog

source

crates/jrsonnet-stdlib/src/manifest/ini.rs2.7 KiBsourcehistory
1use std::collections::BTreeMap;23use jrsonnet_evaluator::{4	manifest::{ManifestFormat, ToStringFormat},5	typed::{FromUntyped, Typed},6	ObjValue, Result, ResultExt, Val,7	IStr,8};910pub struct IniFormat {11	#[cfg(feature = "exp-preserve-order")]12	preserve_order: bool,13	final_newline: bool,14}1516impl IniFormat {17	pub fn std(#[cfg(feature = "exp-preserve-order")] preserve_order: bool) -> Self {18		Self {19			#[cfg(feature = "exp-preserve-order")]20			preserve_order,21			final_newline: true,22		}23	}24	pub fn cli(#[cfg(feature = "exp-preserve-order")] preserve_order: bool) -> Self {25		Self {26			#[cfg(feature = "exp-preserve-order")]27			preserve_order,28			final_newline: false,29		}30	}31}3233impl ManifestFormat for IniFormat {34	fn manifest_buf(&self, val: Val, buf: &mut String) -> Result<()> {35		manifest_ini_obj(36			self,37			IniObj::from_untyped(val).description("ini object structure")?,38			buf,39		)40	}41}4243fn manifest_ini_body(44	#[cfg(feature = "exp-preserve-order")] format: &IniFormat,45	body: ObjValue,46	out: &mut String,47) -> Result<()> {48	for (i, (key, value)) in body49		.iter(50			#[cfg(feature = "exp-preserve-order")]51			format.preserve_order,52		)53		.enumerate()54	{55		if i != 0 || !out.is_empty() {56			out.push('\n');57		}58		let value = value.with_description(|| format!("field <{key}> evaluation"))?;59		let manifest_desc = || format!("field <{key}> manifestification");60		if let Some(arr) = value.as_arr() {61			for (i, ele) in arr.iter().enumerate() {62				if i != 0 {63					out.push('\n');64				}65				let ele = ele66					.with_description(|| format!("elem <{i}> evaluation"))67					.with_description(manifest_desc)?;68				out.push_str(&key);69				out.push_str(" = ");70				ToStringFormat71					.manifest_buf(ele, out)72					.with_description(manifest_desc)?;73			}74		} else {75			out.push_str(&key);76			out.push_str(" = ");77			ToStringFormat78				.manifest_buf(value, out)79				.with_description(manifest_desc)?;80		}81	}82	Ok(())83}8485#[derive(Typed, FromUntyped)]86struct IniObj {87	main: Option<ObjValue>,88	// TODO: Preserve section order?89	sections: BTreeMap<IStr, ObjValue>,90}9192fn manifest_ini_obj(format: &IniFormat, obj: IniObj, out: &mut String) -> Result<()> {93	if let Some(main) = obj.main {94		manifest_ini_body(95			#[cfg(feature = "exp-preserve-order")]96			format,97			main,98			out,99		)100		.description("<main> manifestification")?;101	}102	for (i, (section, val)) in obj.sections.into_iter().enumerate() {103		if i != 0 || !out.is_empty() {104			out.push('\n');105		}106		out.push('[');107		out.push_str(&section);108		out.push(']');109		manifest_ini_body(110			#[cfg(feature = "exp-preserve-order")]111			format,112			val,113			out,114		)115		.with_description(|| format!("<{section}> section manifestification"))?;116	}117	if format.final_newline {118		out.push('\n');119	}120	Ok(())121}