use crate::Diff;
use facet_diff_core::layout::{
AnsiBackend, BuildOptions, ColorBackend, DiffFlavor, JsonFlavor, RenderOptions, RustFlavor,
XmlFlavor, build_layout, render_to_string,
};
use facet_reflect::Peek;
pub struct DiffReport<'mem, 'facet> {
diff: Diff<'mem, 'facet>,
left: Peek<'mem, 'facet>,
right: Peek<'mem, 'facet>,
float_tolerance: Option<f64>,
}
impl<'mem, 'facet> DiffReport<'mem, 'facet> {
pub const fn new(
diff: Diff<'mem, 'facet>,
left: Peek<'mem, 'facet>,
right: Peek<'mem, 'facet>,
) -> Self {
Self {
diff,
left,
right,
float_tolerance: None,
}
}
pub const fn with_float_tolerance(mut self, tolerance: f64) -> Self {
self.float_tolerance = Some(tolerance);
self
}
pub const fn diff(&self) -> &Diff<'mem, 'facet> {
&self.diff
}
pub const fn left(&self) -> Peek<'mem, 'facet> {
self.left
}
pub const fn right(&self) -> Peek<'mem, 'facet> {
self.right
}
pub fn legacy_string(&self) -> String {
format!("{}", self.diff)
}
fn float_precision_from_tolerance(&self) -> Option<usize> {
self.float_tolerance.map(|tol| {
if tol <= 0.0 {
6 } else {
(-tol.log10()).ceil() as usize
}
})
}
fn build_opts_with_precision(&self) -> BuildOptions {
BuildOptions {
float_precision: self.float_precision_from_tolerance(),
..Default::default()
}
}
pub fn render_with_options<B: ColorBackend, F: DiffFlavor>(
&self,
flavor: &F,
build_opts: &BuildOptions,
render_opts: &RenderOptions<B>,
) -> String {
let layout = build_layout(&self.diff, self.left, self.right, build_opts, flavor);
render_to_string(&layout, render_opts, flavor)
}
pub fn render_ansi_with<F: DiffFlavor>(&self, flavor: &F) -> String {
let build_opts = self.build_opts_with_precision();
let render_opts = RenderOptions::<AnsiBackend>::default();
self.render_with_options(flavor, &build_opts, &render_opts)
}
pub fn render_plain_with<F: DiffFlavor>(&self, flavor: &F) -> String {
let build_opts = self.build_opts_with_precision();
let render_opts = RenderOptions::plain();
self.render_with_options(flavor, &build_opts, &render_opts)
}
pub fn render_ansi_rust(&self) -> String {
self.render_ansi_with(&RustFlavor)
}
pub fn render_plain_rust(&self) -> String {
self.render_plain_with(&RustFlavor)
}
pub fn render_ansi_json(&self) -> String {
self.render_ansi_with(&JsonFlavor)
}
pub fn render_plain_json(&self) -> String {
self.render_plain_with(&JsonFlavor)
}
pub fn render_ansi_xml(&self) -> String {
self.render_ansi_with(&XmlFlavor)
}
pub fn render_plain_xml(&self) -> String {
self.render_plain_with(&XmlFlavor)
}
}