sim_lib_doc_core/
fidelity.rs1#[derive(Clone, Debug, Default, PartialEq, Eq)]
5pub struct FidelityReport {
6 pub backend: String,
9 pub dropped: Vec<LossNote>,
11 pub preserved_extras: Vec<String>,
13 pub warnings: Vec<String>,
15}
16
17impl FidelityReport {
18 #[must_use]
20 pub fn new(backend: impl Into<String>) -> Self {
21 Self {
22 backend: backend.into(),
23 ..Self::default()
24 }
25 }
26
27 #[must_use]
29 pub fn is_lossless(&self) -> bool {
30 self.dropped.is_empty()
31 }
32
33 #[must_use]
35 pub fn with_dropped(mut self, field: impl Into<String>, reason: impl Into<String>) -> Self {
36 self.dropped.push(LossNote::new(field, reason));
37 self
38 }
39
40 #[must_use]
42 pub fn with_preserved_extra(mut self, extra: impl Into<String>) -> Self {
43 self.preserved_extras.push(extra.into());
44 self
45 }
46
47 #[must_use]
49 pub fn with_warning(mut self, warning: impl Into<String>) -> Self {
50 self.warnings.push(warning.into());
51 self
52 }
53}
54
55#[derive(Clone, Debug, PartialEq, Eq)]
57pub struct LossNote {
58 pub field: String,
60 pub reason: String,
62}
63
64impl LossNote {
65 #[must_use]
67 pub fn new(field: impl Into<String>, reason: impl Into<String>) -> Self {
68 Self {
69 field: field.into(),
70 reason: reason.into(),
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn warnings_survive_report_building() {
81 let report = FidelityReport::new("codec/plain")
82 .with_preserved_extra("raw-styles")
83 .with_warning("formula cached value differed");
84
85 assert!(report.is_lossless());
86 assert_eq!(report.warnings, vec!["formula cached value differed"]);
87 assert_eq!(report.preserved_extras, vec!["raw-styles"]);
88 }
89
90 #[test]
91 fn dropped_report_is_not_lossless() {
92 let report = FidelityReport::new("codec/plain")
93 .with_dropped("sheet.hiddenRows", "backend does not expose hidden rows");
94
95 assert!(!report.is_lossless());
96 assert_eq!(report.dropped[0].field, "sheet.hiddenRows");
97 }
98}