spielrs_diff/
lib.rs

1//!
2//! # Spielrs Diff
3//! It is a library which compare two directories or two files asynchronously through [tokio](https://tokio.rs)
4//! and return true in case that both are different. Useful to create watchers in the servers
5//!
6//! ## How install it
7//! 1. add the dependency in the Cargo.toml file of the project:
8//!
9//! ```toml
10//! spielrs_diff = "0.2"
11//! ```
12//!
13//! ## Example
14//!
15//! ### Dir comparation
16//! ```rust
17//! use spielrs_diff::{dir_diff, diff::DirDiff};
18//!
19//! #[tokio::test]
20//! async fn should_return_true_if_both_dir_tree_are_different() {
21//!    let diff = dir_diff(DirDiff {
22//!        dir: "./mocks/dir_one".to_string(),
23//!        dir_comp: "./mocks/dir_five".to_string(),
24//!        excluding: Some(vec!["purpose".to_string()]),
25//!        recursive_excluding: true,
26//!    })
27//!    .await;
28//!
29//!    assert_eq!(diff, true);
30//! }
31//! ```
32//!
33//! ### File comparation
34//! ```rust
35//! use spielrs_diff::{file_diff, diff::FileDiff};
36//!
37//! #[tokio::test]
38//! async fn should_return_true_if_both_files_are_not_equal() {
39//!     let diff = file_diff(FileDiff {
40//!         file: "./mocks/dir_one/vlang/purpose/purpose.txt".to_string(),
41//!         file_comp: "./mocks/dir_five/vlang/purpose/purpose.txt".to_string(),
42//!     })
43//!     .await;
44//!
45//!     assert_eq!(diff, true);
46//! }
47//! ```
48pub mod diff;
49pub mod tree;
50
51use diff::{DirDiff, FileDiff};
52use tokio::fs;
53use tree::{Tree, TreeBuilder};
54
55/// Compare two directories and return true if both are different
56/// You can exclude directories or files in the comparation only from the root path
57/// of both or recursively
58///
59/// # Example
60/// ```rust
61/// use spielrs_diff::{dir_diff, diff::DirDiff};
62///
63/// #[tokio::test]
64/// async fn should_return_true_if_both_dir_tree_are_different() {
65///    let diff = dir_diff(DirDiff {
66///        dir: "./mocks/dir_one".to_string(),
67///        dir_comp: "./mocks/dir_five".to_string(),
68///        excluding: Some(vec!["purpose".to_string()]),
69///        recursive_excluding: true,
70///    })
71///    .await;
72///
73///    assert_eq!(diff, true);
74/// }
75/// ```
76///
77pub async fn dir_diff(dir_diff_options: DirDiff) -> bool {
78    let tree_one: Vec<Tree> = Tree::build_tree(
79        dir_diff_options.dir,
80        dir_diff_options.excluding.clone(),
81        dir_diff_options.recursive_excluding,
82    )
83    .await;
84    let tree_two: Vec<Tree> = Tree::build_tree(
85        dir_diff_options.dir_comp,
86        dir_diff_options.excluding,
87        dir_diff_options.recursive_excluding,
88    )
89    .await;
90    if Tree::tree_diff(tree_one.clone(), tree_two.clone()) {
91        return true;
92    }
93
94    let content_one: Vec<String> = Tree::get_content_files(tree_one).await;
95    let content_two: Vec<String> = Tree::get_content_files(tree_two).await;
96    !Tree::compare_dir_content(content_one, content_two)
97}
98
99/// Compare two files and return true if both are different
100///
101/// #Example
102/// ```rust
103/// use spielrs_diff::{file_diff, diff::FileDiff};
104///
105/// #[tokio::test]
106/// async fn should_return_true_if_both_files_are_not_equal() {
107///     let diff = file_diff(FileDiff {
108///         file: "./mocks/dir_one/vlang/purpose/purpose.txt".to_string(),
109///         file_comp: "./mocks/dir_five/vlang/purpose/purpose.txt".to_string(),
110///     })
111///     .await;
112///
113///     assert_eq!(diff, true);
114/// }
115/// ```
116pub async fn file_diff(file_diff_options: FileDiff) -> bool {
117    let file_one = fs::read_to_string(file_diff_options.file).await.unwrap();
118    let file_two = fs::read_to_string(file_diff_options.file_comp)
119        .await
120        .unwrap();
121
122    file_one != file_two
123}
124
125#[tokio::test]
126async fn should_return_true_if_both_dir_tree_are_different() {
127    let diff = dir_diff(DirDiff {
128        dir: "./mocks/dir_one".to_string(),
129        dir_comp: "./mocks/dir_three".to_string(),
130        excluding: None,
131        recursive_excluding: false,
132    })
133    .await;
134    assert_eq!(diff, true);
135}
136
137#[tokio::test]
138async fn should_return_false_if_both_dir_tree_are_equal() {
139    let diff = dir_diff(DirDiff {
140        dir: "./mocks/dir_one".to_string(),
141        dir_comp: "./mocks/dir_two".to_string(),
142        excluding: None,
143        recursive_excluding: false,
144    })
145    .await;
146    assert_eq!(diff, false);
147}
148
149#[tokio::test]
150async fn should_return_true_if_both_dir_tree_have_different_content() {
151    let diff = dir_diff(DirDiff {
152        dir: "./mocks/dir_one".to_string(),
153        dir_comp: "./mocks/dir_four".to_string(),
154        excluding: None,
155        recursive_excluding: false,
156    })
157    .await;
158    assert_eq!(diff, true);
159}
160
161#[tokio::test]
162async fn should_return_false_if_both_dir_have_different_subdir_excluded_recursively() {
163    let diff = dir_diff(DirDiff {
164        dir: "./mocks/dir_one".to_string(),
165        dir_comp: "./mocks/dir_five".to_string(),
166        excluding: Some(vec!["purpose".to_string()]),
167        recursive_excluding: true,
168    })
169    .await;
170    assert_eq!(diff, false);
171}
172
173#[tokio::test]
174async fn should_return_true_if_both_dir_have_different_subdir_excluded_not_recursively() {
175    let diff = dir_diff(DirDiff {
176        dir: "./mocks/dir_one".to_string(),
177        dir_comp: "./mocks/dir_five".to_string(),
178        excluding: Some(vec!["purpose".to_string()]),
179        recursive_excluding: false,
180    })
181    .await;
182    assert_eq!(diff, true);
183}
184
185#[tokio::test]
186async fn should_return_false_if_both_files_are_equal() {
187    let diff = file_diff(FileDiff {
188        file: "./mocks/dir_one/hello.txt".to_string(),
189        file_comp: "./mocks/dir_two/hello.txt".to_string(),
190    })
191    .await;
192
193    assert_eq!(diff, false);
194}
195
196#[tokio::test]
197async fn should_return_true_if_both_files_are_not_equal() {
198    let diff = file_diff(FileDiff {
199        file: "./mocks/dir_one/vlang/purpose/purpose.txt".to_string(),
200        file_comp: "./mocks/dir_five/vlang/purpose/purpose.txt".to_string(),
201    })
202    .await;
203
204    assert_eq!(diff, true);
205}