1 #![allow(clippy::unnecessary_operation)] 2 3 use std::collections::VecDeque; 4 use std::fmt; 5 use std::fs::{Metadata, Permissions}; 6 use std::io; 7 use std::io::prelude::*; 8 use std::io::SeekFrom; 9 use std::path::PathBuf; 10 use std::sync::{Arc, Mutex}; 11 12 pub struct File { 13 shared: Arc<Mutex<Shared>>, 14 } 15 16 pub struct Handle { 17 shared: Arc<Mutex<Shared>>, 18 } 19 20 struct Shared { 21 calls: VecDeque<Call>, 22 } 23 24 #[derive(Debug)] 25 enum Call { 26 Read(io::Result<Vec<u8>>), 27 Write(io::Result<Vec<u8>>), 28 Seek(SeekFrom, io::Result<u64>), 29 SyncAll(io::Result<()>), 30 SyncData(io::Result<()>), 31 SetLen(u64, io::Result<()>), 32 } 33 34 impl Handle { read(&self, data: &[u8]) -> &Self35 pub fn read(&self, data: &[u8]) -> &Self { 36 let mut s = self.shared.lock().unwrap(); 37 s.calls.push_back(Call::Read(Ok(data.to_owned()))); 38 self 39 } 40 read_err(&self) -> &Self41 pub fn read_err(&self) -> &Self { 42 let mut s = self.shared.lock().unwrap(); 43 s.calls 44 .push_back(Call::Read(Err(io::ErrorKind::Other.into()))); 45 self 46 } 47 write(&self, data: &[u8]) -> &Self48 pub fn write(&self, data: &[u8]) -> &Self { 49 let mut s = self.shared.lock().unwrap(); 50 s.calls.push_back(Call::Write(Ok(data.to_owned()))); 51 self 52 } 53 write_err(&self) -> &Self54 pub fn write_err(&self) -> &Self { 55 let mut s = self.shared.lock().unwrap(); 56 s.calls 57 .push_back(Call::Write(Err(io::ErrorKind::Other.into()))); 58 self 59 } 60 seek_start_ok(&self, offset: u64) -> &Self61 pub fn seek_start_ok(&self, offset: u64) -> &Self { 62 let mut s = self.shared.lock().unwrap(); 63 s.calls 64 .push_back(Call::Seek(SeekFrom::Start(offset), Ok(offset))); 65 self 66 } 67 seek_current_ok(&self, offset: i64, ret: u64) -> &Self68 pub fn seek_current_ok(&self, offset: i64, ret: u64) -> &Self { 69 let mut s = self.shared.lock().unwrap(); 70 s.calls 71 .push_back(Call::Seek(SeekFrom::Current(offset), Ok(ret))); 72 self 73 } 74 sync_all(&self) -> &Self75 pub fn sync_all(&self) -> &Self { 76 let mut s = self.shared.lock().unwrap(); 77 s.calls.push_back(Call::SyncAll(Ok(()))); 78 self 79 } 80 sync_all_err(&self) -> &Self81 pub fn sync_all_err(&self) -> &Self { 82 let mut s = self.shared.lock().unwrap(); 83 s.calls 84 .push_back(Call::SyncAll(Err(io::ErrorKind::Other.into()))); 85 self 86 } 87 sync_data(&self) -> &Self88 pub fn sync_data(&self) -> &Self { 89 let mut s = self.shared.lock().unwrap(); 90 s.calls.push_back(Call::SyncData(Ok(()))); 91 self 92 } 93 sync_data_err(&self) -> &Self94 pub fn sync_data_err(&self) -> &Self { 95 let mut s = self.shared.lock().unwrap(); 96 s.calls 97 .push_back(Call::SyncData(Err(io::ErrorKind::Other.into()))); 98 self 99 } 100 set_len(&self, size: u64) -> &Self101 pub fn set_len(&self, size: u64) -> &Self { 102 let mut s = self.shared.lock().unwrap(); 103 s.calls.push_back(Call::SetLen(size, Ok(()))); 104 self 105 } 106 set_len_err(&self, size: u64) -> &Self107 pub fn set_len_err(&self, size: u64) -> &Self { 108 let mut s = self.shared.lock().unwrap(); 109 s.calls 110 .push_back(Call::SetLen(size, Err(io::ErrorKind::Other.into()))); 111 self 112 } 113 remaining(&self) -> usize114 pub fn remaining(&self) -> usize { 115 let s = self.shared.lock().unwrap(); 116 s.calls.len() 117 } 118 } 119 120 impl Drop for Handle { drop(&mut self)121 fn drop(&mut self) { 122 if !std::thread::panicking() { 123 let s = self.shared.lock().unwrap(); 124 assert_eq!(0, s.calls.len()); 125 } 126 } 127 } 128 129 impl File { open(_: PathBuf) -> io::Result<File>130 pub fn open(_: PathBuf) -> io::Result<File> { 131 unimplemented!(); 132 } 133 create(_: PathBuf) -> io::Result<File>134 pub fn create(_: PathBuf) -> io::Result<File> { 135 unimplemented!(); 136 } 137 mock() -> (Handle, File)138 pub fn mock() -> (Handle, File) { 139 let shared = Arc::new(Mutex::new(Shared { 140 calls: VecDeque::new(), 141 })); 142 143 let handle = Handle { 144 shared: shared.clone(), 145 }; 146 let file = File { shared }; 147 148 (handle, file) 149 } 150 sync_all(&self) -> io::Result<()>151 pub fn sync_all(&self) -> io::Result<()> { 152 use self::Call::*; 153 154 let mut s = self.shared.lock().unwrap(); 155 156 match s.calls.pop_front() { 157 Some(SyncAll(ret)) => ret, 158 Some(op) => panic!("expected next call to be {:?}; was sync_all", op), 159 None => panic!("did not expect call"), 160 } 161 } 162 sync_data(&self) -> io::Result<()>163 pub fn sync_data(&self) -> io::Result<()> { 164 use self::Call::*; 165 166 let mut s = self.shared.lock().unwrap(); 167 168 match s.calls.pop_front() { 169 Some(SyncData(ret)) => ret, 170 Some(op) => panic!("expected next call to be {:?}; was sync_all", op), 171 None => panic!("did not expect call"), 172 } 173 } 174 set_len(&self, size: u64) -> io::Result<()>175 pub fn set_len(&self, size: u64) -> io::Result<()> { 176 use self::Call::*; 177 178 let mut s = self.shared.lock().unwrap(); 179 180 match s.calls.pop_front() { 181 Some(SetLen(arg, ret)) => { 182 assert_eq!(arg, size); 183 ret 184 } 185 Some(op) => panic!("expected next call to be {:?}; was sync_all", op), 186 None => panic!("did not expect call"), 187 } 188 } 189 metadata(&self) -> io::Result<Metadata>190 pub fn metadata(&self) -> io::Result<Metadata> { 191 unimplemented!(); 192 } 193 set_permissions(&self, _perm: Permissions) -> io::Result<()>194 pub fn set_permissions(&self, _perm: Permissions) -> io::Result<()> { 195 unimplemented!(); 196 } 197 try_clone(&self) -> io::Result<Self>198 pub fn try_clone(&self) -> io::Result<Self> { 199 unimplemented!(); 200 } 201 } 202 203 impl Read for &'_ File { read(&mut self, dst: &mut [u8]) -> io::Result<usize>204 fn read(&mut self, dst: &mut [u8]) -> io::Result<usize> { 205 use self::Call::*; 206 207 let mut s = self.shared.lock().unwrap(); 208 209 match s.calls.pop_front() { 210 Some(Read(Ok(data))) => { 211 assert!(dst.len() >= data.len()); 212 assert!(dst.len() <= 16 * 1024, "actual = {}", dst.len()); // max buffer 213 214 &mut dst[..data.len()].copy_from_slice(&data); 215 Ok(data.len()) 216 } 217 Some(Read(Err(e))) => Err(e), 218 Some(op) => panic!("expected next call to be {:?}; was a read", op), 219 None => panic!("did not expect call"), 220 } 221 } 222 } 223 224 impl Write for &'_ File { write(&mut self, src: &[u8]) -> io::Result<usize>225 fn write(&mut self, src: &[u8]) -> io::Result<usize> { 226 use self::Call::*; 227 228 let mut s = self.shared.lock().unwrap(); 229 230 match s.calls.pop_front() { 231 Some(Write(Ok(data))) => { 232 assert_eq!(src, &data[..]); 233 Ok(src.len()) 234 } 235 Some(Write(Err(e))) => Err(e), 236 Some(op) => panic!("expected next call to be {:?}; was write", op), 237 None => panic!("did not expect call"), 238 } 239 } 240 flush(&mut self) -> io::Result<()>241 fn flush(&mut self) -> io::Result<()> { 242 Ok(()) 243 } 244 } 245 246 impl Seek for &'_ File { seek(&mut self, pos: SeekFrom) -> io::Result<u64>247 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> { 248 use self::Call::*; 249 250 let mut s = self.shared.lock().unwrap(); 251 252 match s.calls.pop_front() { 253 Some(Seek(expect, res)) => { 254 assert_eq!(expect, pos); 255 res 256 } 257 Some(op) => panic!("expected call {:?}; was `seek`", op), 258 None => panic!("did not expect call; was `seek`"), 259 } 260 } 261 } 262 263 impl fmt::Debug for File { fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result264 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 265 fmt.debug_struct("mock::File").finish() 266 } 267 } 268 269 #[cfg(unix)] 270 impl std::os::unix::io::AsRawFd for File { as_raw_fd(&self) -> std::os::unix::io::RawFd271 fn as_raw_fd(&self) -> std::os::unix::io::RawFd { 272 unimplemented!(); 273 } 274 } 275 276 #[cfg(unix)] 277 impl std::os::unix::io::FromRawFd for File { from_raw_fd(_: std::os::unix::io::RawFd) -> Self278 unsafe fn from_raw_fd(_: std::os::unix::io::RawFd) -> Self { 279 unimplemented!(); 280 } 281 } 282 283 #[cfg(windows)] 284 impl std::os::windows::io::AsRawHandle for File { as_raw_handle(&self) -> std::os::windows::io::RawHandle285 fn as_raw_handle(&self) -> std::os::windows::io::RawHandle { 286 unimplemented!(); 287 } 288 } 289 290 #[cfg(windows)] 291 impl std::os::windows::io::FromRawHandle for File { from_raw_handle(_: std::os::windows::io::RawHandle) -> Self292 unsafe fn from_raw_handle(_: std::os::windows::io::RawHandle) -> Self { 293 unimplemented!(); 294 } 295 } 296