1use crate::cell_diff::CellDiff;
5use crate::registry::FormatFn;
6use crate::span::Span;
7use crate::value::Value;
8
9pub fn compare_params(
11 returned: &[Value],
12 expected: &[Value],
13 param_spans: &[Span],
14 source_texts: &[String],
15) -> Vec<CellDiff> {
16 compare_params_with_formats(returned, expected, param_spans, source_texts, None)
17}
18
19pub fn compare_params_with_formats(
24 returned: &[Value],
25 expected: &[Value],
26 param_spans: &[Span],
27 source_texts: &[String],
28 formats: Option<&[Option<FormatFn>]>,
29) -> Vec<CellDiff> {
30 let mut diffs = Vec::with_capacity(expected.len());
31 for i in 0..expected.len() {
32 let ok = returned[i] == expected[i];
34 let format = formats.and_then(|f| f.get(i)).and_then(|opt| opt.as_ref());
35 let expected_text = if i < source_texts.len() {
36 source_texts[i].clone()
37 } else {
38 render_param_value(&expected[i], format).0
39 };
40 let (actual_text, via_format) = render_param_value(&returned[i], format);
41 diffs.push(CellDiff {
42 column: format!("cell {}", i + 1),
43 span: param_spans[i],
44 expected: expected_text,
45 actual: actual_text,
46 ok,
47 expected_value: Some(expected[i].clone()),
48 actual_value: Some(returned[i].clone()),
49 formatted: via_format,
50 });
51 }
52 diffs
53}
54
55fn render_param_value(value: &Value, format: Option<&FormatFn>) -> (String, bool) {
58 if let Some(f) = format {
59 if let Some(rendered) = f(value) {
60 return (rendered, true);
61 }
62 }
63 (crate::cell_diff::render_cell_value(value), false)
64}