use super::Formatter;
use crate::{Diff, FormatError};
#[derive(Debug)]
pub struct PrettyFormatter {
use_colors: bool,
indent: usize,
}
impl PrettyFormatter {
pub fn new() -> Self {
Self {
use_colors: cfg!(feature = "pretty"),
indent: 2,
}
}
pub fn with_colors(mut self, enabled: bool) -> Self {
self.use_colors = enabled;
self
}
pub fn with_indent(mut self, spaces: usize) -> Self {
self.indent = spaces;
self
}
}
impl Default for PrettyFormatter {
fn default() -> Self {
Self::new()
}
}
impl Formatter for PrettyFormatter {
fn format(&self, diff: &Diff) -> Result<String, FormatError> {
if diff.is_empty() {
return Ok(String::from("No changes"));
}
let mut output = String::new();
for (path, change) in diff.changes() {
use crate::Change;
match change {
Change::Added(val) => {
output.push_str(&format!("+ {}: {:?}\n", path, val));
}
Change::Removed(val) => {
output.push_str(&format!("- {}: {:?}\n", path, val));
}
Change::Modified { from, to } => {
output.push_str(&format!("{}\n", path));
output.push_str(&format!(" - {:?}\n", from));
output.push_str(&format!(" + {:?}\n", to));
}
Change::Elided { reason, count } => {
output.push_str(&format!("~ {}: {} ({} items)\n", path, reason, count));
}
}
}
Ok(output)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Change, Path};
use serde_value::Value;
#[test]
fn test_empty_diff() {
let diff = Diff::new();
let formatter = PrettyFormatter::new();
let output = formatter.format(&diff).unwrap();
assert_eq!(output, "No changes");
}
#[test]
fn test_added() {
let mut diff = Diff::new();
diff.insert(Path::root().field("x"), Change::Added(Value::I64(42)));
let formatter = PrettyFormatter::new();
let output = formatter.format(&diff).unwrap();
assert!(output.contains("+ x:"));
}
}