difftreelog
feat match jsonnet json formatting
in: master
1 file changed
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth203 })203 })204 }204 }205206 pub fn into_string(self) -> Result<Rc<str>> {207 Ok(match self.unwrap_if_lazy()? {208 Val::Bool(true) => "true".into(),209 Val::Bool(false) => "false".into(),210 Val::Null => "null".into(),211 Val::Str(s) => s,212 v => manifest_json_ex(213 &v,214 &ManifestJsonOptions {215 padding: &"",216 mtype: ManifestType::ToString,217 },218 )?219 .into(),220 })221 }222223 /// For manifestification224 pub fn into_json(self, padding: usize) -> Result<Rc<str>> {225 manifest_json_ex(226 &self,227 &ManifestJsonOptions {228 padding: &" ".repeat(padding),229 mtype: ManifestType::Manifest,230 },231 )232 .map(|s| s.into())233 }234235 /// Calls std.manifestJson205 #[cfg(feature = "faster")]236 #[cfg(feature = "faster")]206 pub fn into_json(self, padding: usize) -> Result<Rc<str>> {237 pub fn into_std_json(self, padding: usize) -> Result<Rc<str>> {207 manifest_json_ex(&self, &" ".repeat(padding)).map(|s| s.into())238 manifest_json_ex(239 &self,240 &ManifestJsonOptions {241 padding: &" ".repeat(padding),242 mtype: ManifestType::Std,243 },244 )245 .map(|s| s.into())208 }246 }247248 /// Calls std.manifestJson209 #[cfg(not(feature = "faster"))]249 #[cfg(not(feature = "faster"))]210 pub fn into_json(self, padding: usize) -> Result<Rc<str>> {250 pub fn into_std_json(self, padding: usize) -> Result<Rc<str>> {211 with_state(|s| {251 with_state(|s| {212 let ctx = s252 let ctx = s213 .create_default_context()?253 .create_default_context()?233 with_state(|s| {273 with_state(|s| {234 let ctx = s274 let ctx = s235 .create_default_context()?275 .create_default_context()?236 .with_var("__tmp__to_json__".into(), self)?;276 .with_var("__tmp__to_json__".into(), self);237 Ok(evaluate(277 Ok(evaluate(238 ctx,278 ctx,239 &el!(Expr::Apply(279 &el!(Expr::Apply(314 }354 }315}355}356357#[derive(PartialEq)]358pub enum ManifestType {359 // Applied in manifestification360 Manifest,361 /// Used for std.manifestJson362 /// Empty array/objects extends to "[\n\n]" instead of "[ ]" as in manifest363 Std,364 // No line breaks, used in `obj+''`365 ToString,366}367368pub struct ManifestJsonOptions<'s> {369 pub padding: &'s str,370 pub mtype: ManifestType,371}316372317pub fn manifest_json_ex(val: &Val, padding: &str) -> Result<String> {373pub fn manifest_json_ex(val: &Val, options: &ManifestJsonOptions<'_>) -> Result<String> {318 let mut out = String::new();374 let mut out = String::new();319 manifest_json_ex_buf(val, &mut out, padding, &mut String::new())?;375 manifest_json_ex_buf(val, &mut out, &mut String::new(), options)?;320 Ok(out)376 Ok(out)321}377}322fn manifest_json_ex_buf(378fn manifest_json_ex_buf(323 val: &Val,379 val: &Val,324 buf: &mut String,380 buf: &mut String,325 padding: &str,381 cur_padding: &mut String,326 cur_padding: &mut String,382 options: &ManifestJsonOptions<'_>,327) -> Result<()> {383) -> Result<()> {328 use std::fmt::Write;384 use std::fmt::Write;329 match val.unwrap_if_lazy()? {385 match val.unwrap_if_lazy()? {338 Val::Str(s) => buf.push_str(&escape_string_json(&s)),394 Val::Str(s) => buf.push_str(&escape_string_json(&s)),339 Val::Num(n) => write!(buf, "{}", n).unwrap(),395 Val::Num(n) => write!(buf, "{}", n).unwrap(),340 Val::Arr(items) => {396 Val::Arr(items) => {341 buf.push_str("[\n");397 buf.push('[');342 if !items.is_empty() {398 if !items.is_empty() {399 if options.mtype != ManifestType::ToString {400 buf.push('\n');401 }402343 let old_len = cur_padding.len();403 let old_len = cur_padding.len();344 cur_padding.push_str(padding);404 cur_padding.push_str(options.padding);345 for (i, item) in items.iter().enumerate() {405 for (i, item) in items.iter().enumerate() {346 if i != 0 {406 if i != 0 {407 buf.push(',');408 if options.mtype == ManifestType::ToString {347 buf.push_str(",\n")409 buf.push(' ');410 } else {411 buf.push('\n');412 }348 }413 }349 buf.push_str(cur_padding);414 buf.push_str(cur_padding);350 manifest_json_ex_buf(item, buf, padding, cur_padding)?;415 manifest_json_ex_buf(item, buf, cur_padding, options)?;351 }416 }352 cur_padding.truncate(old_len);417 cur_padding.truncate(old_len);418419 if options.mtype != ManifestType::ToString {420 buf.push('\n');421 buf.push_str(cur_padding);422 }353 }423 } else if options.mtype == ManifestType::Std {354 buf.push('\n');424 buf.push_str("\n\n");355 buf.push_str(cur_padding);425 buf.push_str(cur_padding);426 } else if options.mtype == ManifestType::ToString {427 buf.push(' ');428 }356 buf.push(']');429 buf.push(']');357 }430 }358 Val::Obj(obj) => {431 Val::Obj(obj) => {359 buf.push_str("{\n");432 buf.push('{');360 let fields = obj.visible_fields();433 let fields = obj.visible_fields();361 if !fields.is_empty() {434 if !fields.is_empty() {435 if options.mtype != ManifestType::ToString {436 buf.push('\n');437 }438362 let old_len = cur_padding.len();439 let old_len = cur_padding.len();363 cur_padding.push_str(padding);440 cur_padding.push_str(options.padding);364 for (i, field) in fields.into_iter().enumerate() {441 for (i, field) in fields.into_iter().enumerate() {365 if i != 0 {442 if i != 0 {443 buf.push(',');444 if options.mtype == ManifestType::ToString {366 buf.push_str(",\n")445 buf.push(' ');446 } else {447 buf.push('\n');448 }367 }449 }368 buf.push_str(cur_padding);450 buf.push_str(cur_padding);369 buf.push_str(&escape_string_json(&field));451 buf.push_str(&escape_string_json(&field));370 buf.push_str(": ");452 buf.push_str(": ");371 manifest_json_ex_buf(&obj.get(field)?.unwrap(), buf, padding, cur_padding)?;453 manifest_json_ex_buf(&obj.get(field)?.unwrap(), buf, cur_padding, options)?;372 }454 }373 cur_padding.truncate(old_len);455 cur_padding.truncate(old_len);456457 if options.mtype != ManifestType::ToString {458 buf.push('\n');459 buf.push_str(cur_padding);460 }374 }461 } else if options.mtype == ManifestType::Std {375 buf.push('\n');462 buf.push_str("\n\n");376 buf.push_str(cur_padding);463 buf.push_str(cur_padding);464 } else if options.mtype == ManifestType::ToString {465 buf.push(' ');466 }377 buf.push('}');467 buf.push('}');378 }468 }379 Val::Func(_) | Val::Intristic(_, _) => {469 Val::Func(_) | Val::Intristic(_, _) => {406 out496 out407}497}408409pub fn to_string(val: &Val) -> Result<Rc<str>> {410 Ok(match val.unwrap_if_lazy()? {411 Val::Bool(true) => "true".into(),412 Val::Null => "null".into(),413 Val::Str(s) => s.clone(),414 v => v.clone().into_json(0)?,415 })416}417498418#[test]499#[test]419fn json_test() {500fn json_test() {