diff_ba_rs/
lib.rs

1//! # diff-ba-rs
2//!
3//! diff-ba-rs is a library to get the differences of variables caused by procedures.
4
5/// Module that provides a set of functions used inside macros.
6///
7/// This module is available externally but is not intended to be used.
8pub mod _diff_ba_impl {
9    use tiny_ansi::TinyAnsi;
10    pub fn _dbg(before: &str, after: &str) {
11        for diff in diff::lines(before, after) {
12            match diff {
13                diff::Result::Left(l) => println!("{}", format!("- {l}").red()),
14                diff::Result::Both(l, _) => println!("{}", format!("  {l}")),
15                diff::Result::Right(r) => println!("{}", format!("+ {r}").green()),
16            }
17        }
18    }
19}
20
21/// Module that provides a set of macros.
22pub mod diff_ba {
23    /// Prints the procedural change difference
24    /// and returns the final expression in the procedural block.
25    ///
26    /// This macro works with a `Debug` implementation of the given expression type.
27    ///
28    /// An example:
29    ///
30    /// ```rust
31    /// use diff_ba_rs::prelude::*;
32    ///
33    /// let mut a = 2;
34    /// let b =  diff_ba::dbg!(&a, {
35    ///     a *= 2;
36    ///     a + 1
37    /// });
38    /// // prints:
39    /// // ```
40    /// // - 2
41    /// // + 4
42    /// // ```
43    /// assert_eq!(b, 5);
44    /// ```
45    #[macro_export]
46    macro_rules! dbg_ {
47        ($val:expr, $b:block) => {{
48            let before = format!("{:#?}", $val);
49            let value = $b;
50            let after = format!("{:#?}", $val);
51            _diff_ba_impl::_dbg(&before, &after);
52            value
53        }};
54    }
55    pub use dbg_ as dbg;
56}
57
58/// Prelude module to import when using this crate.
59pub mod prelude {
60    pub use crate::{_diff_ba_impl, diff_ba};
61}
62
63#[cfg(test)]
64mod tests {
65    use crate::prelude::*;
66
67    #[test]
68    fn test_dbg_nothing() {
69        let mut v = Vec::new();
70        v.push("foo");
71        v.push("bar");
72        let result = diff_ba::dbg!(&v, { v.join(", ") });
73        assert_eq!(result, "foo, bar");
74    }
75
76    #[test]
77    fn test_dbg_add() {
78        let mut v = Vec::new();
79        v.push("foo");
80        v.push("bar");
81        let result = diff_ba::dbg!(&v, {
82            v.push("baz");
83            v.join(", ")
84        });
85        assert_eq!(result, "foo, bar, baz");
86    }
87
88    #[test]
89    fn test_dbg_sub() {
90        let mut v = Vec::new();
91        v.push("foo");
92        v.push("bar");
93        let result = diff_ba::dbg!(&v, {
94            v.pop();
95            v.join(", ")
96        });
97        assert_eq!(result, "foo");
98    }
99
100    #[test]
101    fn test_dbg_mix() {
102        let mut v = Vec::new();
103        v.push("foo");
104        v.push("bar");
105        let result = diff_ba::dbg!(&v, {
106            v.pop();
107            v.push("baz");
108            v.join(", ")
109        });
110        assert_eq!(result, "foo, baz");
111    }
112}