difference_rs/
display.rs

1use super::{Changeset, Difference};
2use std::fmt;
3
4impl fmt::Display for Changeset {
5    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6        for d in &self.diffs {
7            match *d {
8                Difference::Same(ref x) => {
9                    write!(f, "{}{}", x, self.split)?;
10                }
11                Difference::Add(ref x) => {
12                    write!(f, "\x1b[92m{}\x1b[0m{}", x, self.split)?;
13                }
14                Difference::Rem(ref x) => {
15                    write!(f, "\x1b[91m{}\x1b[0m{}", x, self.split)?;
16                }
17            }
18        }
19        Ok(())
20    }
21}
22
23#[cfg(test)]
24mod tests {
25    use super::super::Changeset;
26    use std::io::Write;
27    use std::iter::FromIterator;
28    use std::thread;
29    use std::time;
30
31    /// convert slice to vector for assert_eq
32    fn vb(b: &'static [u8]) -> Vec<u8> {
33        Vec::from_iter(b.iter().cloned())
34    }
35
36    /// if the format changes, you can use this to help create the test for color
37    /// just pass it in and copy-paste (validating that it looks right first of course...)
38    #[allow(dead_code)]
39    fn debug_bytes(result: &[u8], expected: &[u8]) {
40        // sleep for a bit so stderr passes us
41        thread::sleep(time::Duration::new(0, 2e8 as u32));
42        println!("Debug Result:");
43        for b in result {
44            print!("{}", *b as char);
45        }
46        println!("Repr Result:");
47        repr_bytes(result);
48        println!();
49        println!("--Result Repr DONE");
50
51        println!("Debug Expected:");
52        for b in expected {
53            print!("{}", *b as char);
54        }
55        println!("Repr Expected:");
56        repr_bytes(expected);
57        println!();
58        println!("--Expected Repr DONE");
59    }
60
61    /// for helping debugging what the actual bytes are
62    /// for writing user tests
63    fn repr_bytes(bytes: &[u8]) {
64        for b in bytes {
65            match *b {
66                // 9 => print!("{}", *b as char), // TAB
67                b'\n' => print!("\\n"),
68                b'\r' => print!("\\r"),
69                32..=126 => print!("{}", *b as char), // visible ASCII
70                _ => print!(r"\x{:0>2x}", b),
71            }
72        }
73    }
74
75    #[test]
76    fn test_display() {
77        let text1 = "Roses are red, violets are blue,\n\
78                     I wrote this library,\n\
79                     just for you.\n\
80                     (It's true).";
81
82        let text2 = "Roses are red, violets are blue,\n\
83                     I wrote this documentation,\n\
84                     just for you.\n\
85                     (It's quite true).";
86        let expected = b"Roses are red, violets are blue,\n\x1b[91mI wrote this library,\x1b\
87            [0m\n\x1b[92mI wrote this documentation,\x1b[0m\njust for you.\n\x1b\
88            [91m(It's true).\x1b[0m\n\x1b[92m(It's quite true).\x1b[0m\n";
89
90        let ch = Changeset::new(text1, text2, "\n");
91        let mut result: Vec<u8> = Vec::new();
92        write!(result, "{}", ch).unwrap();
93        debug_bytes(&result, expected);
94        assert_eq!(result, vb(expected));
95    }
96}