File: lib.rs

package info (click to toggle)
rust-coreutils 0.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 505,620 kB
  • sloc: ansic: 103,594; asm: 28,570; sh: 8,910; python: 5,581; makefile: 472; cpp: 97; javascript: 72
file content (107 lines) | stat: -rw-r--r-- 3,050 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// (c) 2014, Ethan Pailes
// All Rights Reserved
//
// Licensed under the "Revised" BSD 3-clause licence. See LICENCE file at the
// root directory of this repository.

//! File Diff
//!
//! This module provides an atomic file diffing function for use in unit tests.
//!
//! The diff_files() function takes two file handles and determines returns true
//! if they point to identical files.
//!
//! ```
//! use file_diff::{diff_files};
//! use std::fs::{File};
//!
//! let mut file1 = match File::open("./src/lib.rs") {
//!     Ok(f) => f,
//!     Err(e) => panic!("{}", e),
//! };
//! let mut file2 = match File::open("./src/lib.rs") {
//!     Ok(f) => f,
//!     Err(e) => panic!("{}", e),
//! };
//!
//! diff_files(&mut file1, &mut file2);
//! ```
//!
//! The diff() function takes string representations of the files and returns true
//! if the strings represent real files and those files are identical.
//!
//! ```
//! use file_diff::{diff};
//!
//! diff("./src/lib.rs", "./src/lib.rs");
//! ```

use std::io::Read;



use std::fs::{File};


/// Takes two file arguments and returns true if the two files are identical.
pub fn diff_files(f1: &mut File, f2: &mut File) -> bool {

    let mut buff1 : &mut [u8] = &mut [0; 1024];
    let mut buff2 : &mut [u8] = &mut [0; 1024];
    
    loop {

        match f1.read(buff1) {
            Err(_) => return false,
            Ok(f1_read_len) => match f2.read(buff2) {
                Err(_) => return false,
                Ok(f2_read_len) => {
                    if f1_read_len != f2_read_len {
                        return false;
                    }
                    if f1_read_len == 0 {
                        return true;
                    }
                    if &buff1[0..f1_read_len] != &buff2[0..f2_read_len] {
                        return false;
                    }
                }
            }
        }
    }
}

/// Takes two string filepaths and returns true if the two files are identical and exist.
pub fn diff(f1: &str, f2: &str) -> bool {
    let mut fh1 = File::open(f1);
    let mut fh2 = File::open(f2);

    fh1.as_mut().and_then(|file1|
        fh2.as_mut().and_then(|file2|
            Ok(diff_files(file1, file2)))).unwrap_or(false)
}

#[cfg(test)]
mod tests {
    const LIB_RS: &'static str = "./src/lib.rs";
    const CARGO_FILE: &'static str = "./Cargo.toml";
    const RUST_BIN_FILE: &'static str = "./testdata/rust_hello";
    const C_BIN_FILE: &'static str = "./testdata/c_hello";
    const C_BIN_FILE_COPY: &'static str = "./testdata/c_hello_copy";

    #[test]
    fn diff_the_same_text_file() { assert!(super::diff(LIB_RS, LIB_RS)); }

    #[test]
    fn diff_the_same_binary_file() { assert!(super::diff(RUST_BIN_FILE, RUST_BIN_FILE)); }

    #[test]
    fn diff_identical_binary_files() { assert!(super::diff(C_BIN_FILE, C_BIN_FILE_COPY)); }

    #[test]
    fn diff_different_text_files() { assert!( !super::diff(LIB_RS, CARGO_FILE)); }

    #[test]
    fn diff_different_binary_files() { assert!( !super::diff(RUST_BIN_FILE, C_BIN_FILE)); }
}