1use difference::{Changeset, Difference};
2use serde::Serialize;
3use std::fmt;
4
5fn prefix_lines(prefix: &str, lines: &str) -> String {
8 lines
9 .lines()
10 .map(|i| [prefix, i].concat())
11 .collect::<Vec<String>>()
12 .join("\n")
13}
14
15pub struct Diff(Changeset);
17
18impl Diff {
19 pub fn new(left: &str, right: &str) -> Self {
20 Self(Changeset::new(left, right, "\n"))
21 }
22}
23
24impl fmt::Display for Diff {
25 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26 for d in &self.0.diffs {
27 match *d {
28 Difference::Same(ref x) => {
29 write!(f, "{}{}", prefix_lines(" ", x), self.0.split)?;
30 }
31 Difference::Add(ref x) => {
32 write!(f, "\x1b[92m{}\x1b[0m{}", prefix_lines("+", x), self.0.split)?;
33 }
34 Difference::Rem(ref x) => {
35 write!(f, "\x1b[91m{}\x1b[0m{}", prefix_lines("-", x), self.0.split)?;
36 }
37 }
38 }
39 Ok(())
40 }
41}
42
43#[macro_export]
46macro_rules! assert_strings_eq {
47 ($left:expr, $right:expr,) => {{
48 assert_strings_eq!($left, $right)
49 }};
50 ($left:expr, $right:expr) => {{
51 match (&($left), &($right)) {
52 (left_val, right_val) => {
53 if *left_val != *right_val {
54 panic!(
55 "assertion failed: `(left == right)`\ndiff:\n{}",
56 Diff::new(left_val, right_val),
57 )
58 }
59 }
60 }
61 }};
62 ($left:expr, $right:expr, $($args:tt)*) => {{
63 match (&($left), &($right)) {
64 (left_val, right_val) => {
65 if *left_val != *right_val {
66 panic!(
67 "assertion failed: `(left == right)`: {}\ndiff:\n{}",
68 format_args!($($args)*),
69 Diff::new(left_val, right_val),
70 )
71 }
72 }
73 }
74 }};
75}
76
77pub fn to_ron_string_pretty<T>(value: &T) -> ron::ser::Result<String>
80where
81 T: Serialize,
82{
83 let config = ron::ser::PrettyConfig {
84 indentor: " ".to_string(),
85 ..Default::default()
86 };
87
88 let mut serializer = ron::ser::Serializer::new(Some(config), true);
89 value.serialize(&mut serializer)?;
90
91 Ok(serializer.into_output_string())
92}