git.delta.rocks / jrsonnet / refs/heads / master

difftreelog

source

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