difftreelog
feat add description stacktrace frames for all formats
in: master
5 files changed
crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth183 cur_padding: &mut String,183 cur_padding: &mut String,184 options: &JsonFormat<'_>,184 options: &JsonFormat<'_>,185) -> Result<()> {185) -> Result<()> {186 use JsonFormatting::*;187186 let mtype = options.mtype;188 let mtype = options.mtype;187 match val {189 match val {218 }220 }219 Val::Arr(items) => {221 Val::Arr(items) => {220 buf.push('[');222 buf.push('[');221 if !items.is_empty() {222 if mtype != JsonFormatting::ToString && mtype != JsonFormatting::Minify {223 buf.push_str(options.newline);224 }225223226 let old_len = cur_padding.len();224 let old_len = cur_padding.len();227 cur_padding.push_str(&options.padding);225 cur_padding.push_str(&options.padding);226227 let mut had_items = false;228 for (i, item) in items.iter().enumerate() {228 for (i, item) in items.iter().enumerate() {229 had_items = true;230 let item = item.with_description(|| format!("elem <{i}> evaluation"))?;231229 if i != 0 {232 if i != 0 {233 buf.push(',');234 }235 match mtype {236 Manifest | Std => {230 buf.push(',');237 buf.push_str(options.newline);231 if mtype == JsonFormatting::ToString {238 buf.push_str(cur_padding);239 }232 buf.push(' ');240 ToString => buf.push(' '),233 } else if mtype != JsonFormatting::Minify {241 Minify => {}234 buf.push_str(options.newline);235 }236 }242 };243237 buf.push_str(cur_padding);244 buf.push_str(cur_padding);238 manifest_json_ex_buf(&item?, buf, cur_padding, options)239 .with_description(|| format!("elem <{i}> manifestification"))?;245 State::push_description(246 || format!("elem <{i}> manifestification"),247 || manifest_json_ex_buf(&item, buf, cur_padding, options),248 )?;240 }249 }250241 cur_padding.truncate(old_len);251 cur_padding.truncate(old_len);242252253 match mtype {254 Manifest | ToString if !had_items => {255 // Empty array as "[ ]"256 buf.push(' ');257 }243 if mtype != JsonFormatting::ToString && mtype != JsonFormatting::Minify {258 Manifest => {244 buf.push_str(options.newline);259 buf.push_str(options.newline);245 buf.push_str(cur_padding);260 buf.push_str(cur_padding);246 }261 }247 } else if mtype == JsonFormatting::Std {262 Std => {263 if !had_items {264 // Stdlib formats empty array as "[\n\n]"248 buf.push_str(options.newline);265 buf.push_str(options.newline);266 }249 buf.push_str(options.newline);267 buf.push_str(options.newline);250 buf.push_str(cur_padding);268 buf.push_str(cur_padding);251 } else if mtype == JsonFormatting::ToString || mtype == JsonFormatting::Manifest {269 }252 buf.push(' ');270 Minify | ToString => {}253 }271 }272254 buf.push(']');273 buf.push(']');255 }274 }256 Val::Obj(obj) => {275 Val::Obj(obj) => {257 obj.run_assertions()?;276 obj.run_assertions()?;258 buf.push('{');277 buf.push('{');259 let fields = obj.fields(260 #[cfg(feature = "exp-preserve-order")]261 options.preserve_order,262 );263 if !fields.is_empty() {264 if mtype != JsonFormatting::ToString && mtype != JsonFormatting::Minify {265 buf.push_str(options.newline);266 }267278268 let old_len = cur_padding.len();279 let old_len = cur_padding.len();269 cur_padding.push_str(&options.padding);280 cur_padding.push_str(&options.padding);281282 let mut had_fields = false;270 for (i, field) in fields.into_iter().enumerate() {283 for (i, (key, value)) in obj284 .iter(285 #[cfg(feature = "exp-preserve-order")]286 options.preserve_order,287 )288 .enumerate()289 {290 had_fields = true;291 let value = value.with_description(|| format!("field <{key}> evaluation"))?;292271 if i != 0 {293 if i != 0 {272 buf.push(',');294 buf.push(',');273 if mtype == JsonFormatting::ToString {274 buf.push(' ');275 } else if mtype != JsonFormatting::Minify {276 buf.push_str(options.newline);277 }278 }295 }296 match mtype {297 Manifest | Std => {298 buf.push_str(options.newline);279 buf.push_str(cur_padding);299 buf.push_str(cur_padding);300 }301 ToString => buf.push(' '),302 Minify => {}303 }304280 escape_string_json_buf(&field, buf);305 escape_string_json_buf(&key, buf);281 buf.push_str(options.key_val_sep);306 buf.push_str(options.key_val_sep);282 State::push_description(307 State::push_description(283 || format!("field <{}> manifestification", field.clone()),308 || format!("field <{key}> manifestification"),284 || {309 || manifest_json_ex_buf(&value, buf, cur_padding, options),285 let value = obj.get(field.clone())?.unwrap();286 manifest_json_ex_buf(&value, buf, cur_padding, options)?;287 Ok(())288 },289 )?;310 )?;290 }311 }312291 cur_padding.truncate(old_len);313 cur_padding.truncate(old_len);292314315 match mtype {316 Manifest | ToString if !had_fields => {317 // Empty object as "{ }"318 buf.push(' ');319 }293 if mtype != JsonFormatting::ToString && mtype != JsonFormatting::Minify {320 Manifest => {294 buf.push_str(options.newline);321 buf.push_str(options.newline);295 buf.push_str(cur_padding);322 buf.push_str(cur_padding);296 }323 }297 } else if mtype == JsonFormatting::Std {324 Std => {325 if !had_fields {326 // Stdlib formats empty object as "{\n\n}"298 buf.push_str(options.newline);327 buf.push_str(options.newline);328 }299 buf.push_str(options.newline);329 buf.push_str(options.newline);300 buf.push_str(cur_padding);330 buf.push_str(cur_padding);301 } else if mtype == JsonFormatting::ToString || mtype == JsonFormatting::Manifest {331 }302 buf.push(' ');332 Minify | ToString => {}303 }333 }334304 buf.push('}');335 buf.push('}');305 }336 }350 Self {381 Self {351 inner,382 inner,352 c_document_end,383 c_document_end,353 // Stdlib format always inserts newline at the end384 // Stdlib format always inserts useless newline at the end354 end_newline: true,385 end_newline: true,355 }386 }356 }387 }371 )402 )372 };403 };373 if !arr.is_empty() {404 if !arr.is_empty() {374 for v in arr.iter() {405 for (i, v) in arr.iter().enumerate() {375 let v = v?;406 let v = v.with_description(|| format!("elem <{i}> evaluation"))?;376 out.push_str("---\n");407 out.push_str("---\n");408 State::push_description(409 || format!("elem <{i}> manifestification"),377 self.inner.manifest_buf(v, out)?;410 || self.inner.manifest_buf(v, out),411 )?;378 out.push('\n');412 out.push('\n');379 }413 }380 }414 }crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth11 function::{native::NativeDesc, FuncDesc, FuncVal},11 function::{native::NativeDesc, FuncDesc, FuncVal},12 typed::CheckType,12 typed::CheckType,13 val::{IndexableVal, StrValue, ThunkMapper},13 val::{IndexableVal, StrValue, ThunkMapper},14 ObjValue, ObjValueBuilder, Result, Thunk, Val,14 ObjValue, ObjValueBuilder, Result, ResultExt, Thunk, Val,15};15};161617#[derive(Trace)]17#[derive(Trace)]359 unreachable!("typecheck should fail")359 unreachable!("typecheck should fail")360 };360 };361 a.iter()361 a.iter()362 .enumerate()362 .map(|r| r.and_then(T::from_untyped))363 .map(|(i, r)| {364 r.and_then(|t| {365 T::from_untyped(t).with_description(|| format!("parsing elem <{i}>"))366 })367 })363 .collect::<Result<Self>>()368 .collect::<Result<Self>>()364 }369 }365}370}crates/jrsonnet-stdlib/src/manifest/toml.rsdiffbeforeafterboth4 bail,4 bail,5 manifest::{escape_string_json_buf, ManifestFormat},5 manifest::{escape_string_json_buf, ManifestFormat},6 val::ArrValue,6 val::ArrValue,7 IStr, ObjValue, Result, Val,7 IStr, ObjValue, Result, ResultExt, Val, State,8};8};9910pub struct TomlFormat<'s> {10pub struct TomlFormat<'s> {106 #[cfg(feature = "exp-bigint")]106 #[cfg(feature = "exp-bigint")]107 Val::BigInt(n) => write!(buf, "{n}").unwrap(),107 Val::BigInt(n) => write!(buf, "{n}").unwrap(),108 Val::Arr(a) => {108 Val::Arr(a) => {109 if a.is_empty() {110 buf.push_str("[]");109 buf.push('[');111 return Ok(());110112 }111 let mut had_items = false;113 for (i, e) in a.iter().enumerate() {112 for (i, e) in a.iter().enumerate() {113 had_items = true;114 let e = e?;114 let e = e.with_description(|| format!("elem <{i}> evaluation"))?;115115 if i != 0 {116 if i != 0 {116 buf.push(',');117 buf.push(',');117 } else {118 }118 buf.push('[');119 }120 if inline {119 if inline {121 buf.push(' ');120 buf.push(' ');122 } else {121 } else {125 buf.push_str(&options.padding);124 buf.push_str(&options.padding);126 }125 }126127 State::push_description(128 || format!("elem <{i}> manifestification"),127 manifest_value(&e, true, buf, "", options)?;129 || manifest_value(&e, true, buf, "", options),130 )?;128 }131 }132133 if !had_items {129 if inline {134 } else if inline {130 buf.push(' ');135 buf.push(' ');131 } else {136 } else {132 buf.push('\n');137 buf.push('\n');135 buf.push(']');140 buf.push(']');136 }141 }137 Val::Obj(o) => {142 Val::Obj(o) => {138 if o.is_empty() {143 o.run_assertions()?;139 buf.push_str("{}");140 }141 buf.push_str("{ ");144 buf.push('{');145146 let mut had_fields = false;142 for (i, (k, v)) in o147 for (i, (k, v)) in o143 .iter(148 .iter(144 #[cfg(feature = "exp-preserve-order")]149 #[cfg(feature = "exp-preserve-order")]145 options.preserve_order,150 options.preserve_order,146 )151 )147 .enumerate()152 .enumerate()148 {153 {154 had_fields = true;149 let v = v?;155 let v = v.with_description(|| format!("field <{k}> evaluation"))?;156150 if i != 0 {157 if i != 0 {151 buf.push_str(", ");158 buf.push(',');152 }159 }160 buf.push(' ');161153 escape_key_toml_buf(&k, buf);162 escape_key_toml_buf(&k, buf);154 buf.push_str(" = ");163 buf.push_str(" = ");164 State::push_description(165 || format!("field <{k}> manifestification"),155 manifest_value(&v, true, buf, "", options)?;166 || manifest_value(&v, true, buf, "", options),167 )?;156 }168 }169170 if had_fields {171 buf.push(' ');172 }173157 buf.push_str(" }");174 buf.push('}');158 }175 }159 Val::Null => {176 Val::Null => {160 bail!("tried to manifest null")177 bail!("tried to manifest null")crates/jrsonnet-stdlib/src/manifest/xml.rsdiffbeforeafterboth1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{2 bail,2 bail,3 manifest::{ManifestFormat, ToStringFormat},3 manifest::{ManifestFormat, ToStringFormat},4 typed::{ComplexValType, Either4, Typed, ValType},4 typed::{ComplexValType, Either2, Either4, Typed, ValType},5 val::{ArrValue, IndexableVal},5 val::{ArrValue, IndexableVal},6 Either, ObjValue, Result, ResultExt, Val,6 Either, ObjValue, Result, ResultExt, Val, State,7};7};889pub struct XmlJsonmlFormat {9pub struct XmlJsonmlFormat {38 }38 }393940 fn from_untyped(untyped: Val) -> Result<Self> {40 fn from_untyped(untyped: Val) -> Result<Self> {41 let val = <Either![ArrValue, String]>::from_untyped(untyped)42 .with_description(|| format!("parsing JSONML value (an array or string)"))?;41 let Val::Arr(arr) = untyped else {43 let arr = match val {44 Either2::A(a) => a,42 if let Val::Str(s) = untyped {45 Either2::B(s) => return Ok(Self::String(s)),43 return Ok(Self::String(s.to_string()));44 };45 bail!("expected JSONML value (an array or string)");46 };46 };47 if arr.len() < 1 {47 if arr.len() < 1 {48 bail!("JSONML value should have tag");48 bail!("JSONML value should have tag (array length should be >=1)");49 };49 };50 let tag = String::from_untyped(50 let tag = String::from_untyped(51 arr.get(0)51 arr.get(0)52 .with_description(|| "getting JSONML tag")?52 .with_description(|| "getting JSONML tag")?53 .expect("length checked"),53 .expect("length checked"),54 )?;54 )55 .with_description(|| format!("parsing JSONML tag"))?;5655 let (has_attrs, attrs) = if arr.len() >= 2 {57 let (has_attrs, attrs) = if arr.len() >= 2 {56 let maybe_attrs = arr58 let maybe_attrs = arr68 Ok(Self::Tag {70 Ok(Self::Tag {69 tag,71 tag,70 attrs,72 attrs,71 children: Typed::from_untyped(Val::Arr(arr.slice(73 children: State::push_description(74 || format!("parsing children"),75 || {76 Typed::from_untyped(Val::Arr(arr.slice(72 Some(if has_attrs { 2 } else { 1 }),77 Some(if has_attrs { 2 } else { 1 }),73 None,78 None,74 None,79 None,75 )))?,80 )))81 },82 )?,76 })83 })77 }84 }78}85}crates/jrsonnet-stdlib/src/manifest/yaml.rsdiffbeforeafterboth3use jrsonnet_evaluator::{3use jrsonnet_evaluator::{4 bail,4 bail,5 manifest::{escape_string_json_buf, ManifestFormat},5 manifest::{escape_string_json_buf, ManifestFormat},6 Result, Val,6 Result, ResultExt, State, Val,7};7};889pub struct YamlFormat<'s> {9pub struct YamlFormat<'s> {152 #[cfg(feature = "exp-bigint")]152 #[cfg(feature = "exp-bigint")]153 Val::BigInt(n) => write!(buf, "{}", *n).unwrap(),153 Val::BigInt(n) => write!(buf, "{}", *n).unwrap(),154 Val::Arr(a) => {154 Val::Arr(a) => {155 if a.is_empty() {156 buf.push_str("[]");155 let mut had_items = false;157 } else {158 for (i, item) in a.iter().enumerate() {156 for (i, item) in a.iter().enumerate() {157 had_items = true;158 let item = item.with_description(|| format!("elem <{i}> evaluation"))?;159 if i != 0 {159 if i != 0 {160 buf.push('\n');160 buf.push('\n');161 buf.push_str(cur_padding);161 buf.push_str(cur_padding);162 }162 }163 let item = item?;164 buf.push('-');163 buf.push('-');165 match &item {164 match &item {166 Val::Arr(a) if !a.is_empty() => {165 Val::Arr(a) if !a.is_empty() => {179 if extra_padding {178 if extra_padding {180 cur_padding.push_str(&options.padding);179 cur_padding.push_str(&options.padding);181 }180 }181 State::push_description(182 || format!("elem <{i}> manifestification"),182 manifest_yaml_ex_buf(&item, buf, cur_padding, options)?;183 || manifest_yaml_ex_buf(&item, buf, cur_padding, options),184 )?;183 cur_padding.truncate(prev_len);185 cur_padding.truncate(prev_len);184 }186 }185 }187 if !had_items {188 buf.push_str("[]");189 }186 }190 }187 Val::Obj(o) => {191 Val::Obj(o) => {188 if o.is_empty() {189 buf.push_str("{}");192 let mut had_fields = false;190 } else {191 for (i, key) in o193 for (i, (key, value)) in o192 .fields(194 .iter(193 #[cfg(feature = "exp-preserve-order")]195 #[cfg(feature = "exp-preserve-order")]194 options.preserve_order,196 options.preserve_order,195 )197 )196 .iter()197 .enumerate()198 .enumerate()198 {199 {200 had_fields = true;201 let value = value.with_description(|| format!("field <{key}> evaluation"))?;199 if i != 0 {202 if i != 0 {200 buf.push('\n');203 buf.push('\n');201 buf.push_str(cur_padding);204 buf.push_str(cur_padding);202 }205 }203 if !options.quote_keys && !yaml_needs_quotes(key) {206 if !options.quote_keys && !yaml_needs_quotes(&key) {204 buf.push_str(key);207 buf.push_str(&key);205 } else {208 } else {206 escape_string_json_buf(key, buf);209 escape_string_json_buf(&key, buf);207 }210 }208 buf.push(':');211 buf.push(':');209 let prev_len = cur_padding.len();212 let prev_len = cur_padding.len();210 let item = o.get(key.clone())?.expect("field exists");211 match &item {213 match &value {212 Val::Arr(a) if !a.is_empty() => {214 Val::Arr(a) if !a.is_empty() => {213 buf.push('\n');215 buf.push('\n');214 buf.push_str(cur_padding);216 buf.push_str(cur_padding);223 }225 }224 _ => buf.push(' '),226 _ => buf.push(' '),225 }227 }228 State::push_description(229 || format!("field <{key}> manifestification"),226 manifest_yaml_ex_buf(&item, buf, cur_padding, options)?;230 || manifest_yaml_ex_buf(&value, buf, cur_padding, options),231 )?;227 cur_padding.truncate(prev_len);232 cur_padding.truncate(prev_len);228 }233 }229 }234 if !had_fields {235 buf.push_str("{}");236 }230 }237 }231 Val::Func(_) => bail!("tried to manifest function"),238 Val::Func(_) => bail!("tried to manifest function"),232 }239 }