1use rand::Rng;
6use std::io::Read;
7use std::path::Path;
8use std::io::Write;
9use std::fs::OpenOptions;
10use std::io::SeekFrom;
11use std::io::Seek;
12
13#[derive(Debug)]
14pub struct TestTempFile {
15 filename: String,
16 random_number: i32,
17 final_filename: String,
18 file: std::fs::File
19}
20
21impl Drop for TestTempFile {
22 fn drop(&mut self) {
23 self.delete_file();
24 }
25}
26
27impl Write for TestTempFile {
28 fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
29 self.file.write(buf)
30 }
31
32 fn flush(&mut self) -> std::io::Result<()> {
33 self.file.flush()
34 }
35
36 fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
37 self.file.write_all(buf)
38 }
39}
40
41impl Read for TestTempFile {
42 fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
43 self.file.read(buf)
44 }
45}
46
47impl Seek for TestTempFile {
48 fn seek(&mut self, pos: SeekFrom) -> std::io::Result<u64> { self.file.seek(pos) }
49}
50
51impl TestTempFile {
52 pub fn new(filename: String) -> TestTempFile {
63 TestTempFile::gen_random_name(filename)
64 }
65
66 fn gen_random_name(filename: String) -> TestTempFile {
67 let mut rng = rand::thread_rng();
68 let random_number = rng.gen_range(0, i32::max_value());
69 let final_filename = format!("_{}_{}", random_number, filename);
70 let file = OpenOptions::new().
71 create(true).
72 write(true).
73 read(true).
74 open(final_filename.clone()).unwrap();
75 TestTempFile {
76 filename,
77 random_number,
78 final_filename,
79 file
80 }
81 }
82
83 fn delete_file(&mut self) {
84 let final_filename = self.final_filename.as_str();
85 if Path::new(final_filename).exists() {
86 std::fs::remove_file(final_filename);
87 }
88 }
89}
90
91
92#[cfg(test)]
93mod tests {
94 use super::*;
95
96 use std::str;
97
98 static FILE_NAME: &'static str = "test_file.txt";
99
100 #[test]
101 fn test_constructor() {
102 let t = TestTempFile::new(String::from(FILE_NAME));
103 assert_eq!(FILE_NAME, t.filename);
104 }
105
106 #[test]
107 fn test_write() {
108 let mut t = TestTempFile::new(String::from(FILE_NAME));
109 match t.write_all(b"some bytes") {
110 Ok(_) => assert!(true),
111 Err(e) => assert!(false, e)
112 }
113 }
114
115 #[test]
116 fn test_write_and_read() {
117 let mut t = TestTempFile::new(String::from(FILE_NAME));
118 let mut buffer = [0; 10];
119 let msg = b"some bytes";
120 match t.write_all(msg) {
121 Ok(_) => assert!(true),
122 Err(e) => assert!(false, e)
123 }
124
125 t.seek(SeekFrom::Start(0));
128
129 match t.read(&mut buffer[..]) {
130 Ok(n) => {
131 assert_eq!(msg,
132 &buffer[..n],
133 "Left:{:#?}\nRight:{:#?}\n{:#?}",
134 msg, &buffer[..n], t)
135 },
136 Err(e) => assert!(false, format!("Error:{}\n{:#?}", e.to_string(), t))
137 }
138 }
139}