uncloneable/
uncloneable.rs1extern crate pseudo;
2
3use std::{fmt, io};
4use std::fmt::{Display, Formatter};
5use std::error::Error;
6use std::io::ErrorKind;
7use std::path::{Path, PathBuf};
8
9use pseudo::Mock;
10
11trait FileSystem: Clone {
12 fn copy<P: AsRef<Path>, Q: AsRef<Path>>(&self, from: P, to: Q) -> io::Result<()>;
13}
14
15fn copy_to_all<FS: FileSystem, P: AsRef<Path>>(fs: &FS, from: P, to: &[P]) -> Vec<io::Result<()>> {
16 to.iter()
17 .map(|path| fs.copy(&from, &path))
18 .collect::<Vec<io::Result<()>>>()
19}
20
21#[derive(Debug, Clone)]
22struct MockFileSystem<'a> {
23 pub copy: Mock<(PathBuf, PathBuf), Result<(), CloneableError<'a>>>,
24}
25
26impl<'a> FileSystem for MockFileSystem<'a> {
27 fn copy<P: AsRef<Path>, Q: AsRef<Path>>(&self, from: P, to: Q) -> io::Result<()> {
28 let args = (from.as_ref().to_path_buf(), to.as_ref().to_path_buf());
29 self.copy.call(args).map_err(|err| {
30 let (kind, description) = (err.kind, err.description);
31 io::Error::new(kind, description)
32 })
33 }
34}
35
36impl<'a> Default for MockFileSystem<'a> {
37 fn default() -> Self {
38 MockFileSystem {
39 copy: Mock::new(Ok(())),
40 }
41 }
42}
43
44#[derive(Debug, Clone)]
45struct CloneableError<'a> {
46 pub kind: io::ErrorKind,
47 pub description: &'a str,
48}
49
50impl<'a> Error for CloneableError<'a> {
51 fn description(&self) -> &str {
52 self.description
53 }
54}
55
56impl<'a> Display for CloneableError<'a> {
57 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
58 write!(f, "{}", self.description())
59 }
60}
61
62fn main() {
63 let mock = MockFileSystem::default();
65
66 let result = copy_to_all(&mock, "from", &["to"]);
67
68 assert!(result.iter().all(|res| res.is_ok()));
69
70 assert_eq!(mock.copy.num_calls(), 1);
71 let expected_args = (
72 Path::new("from").to_path_buf(),
73 Path::new("to").to_path_buf(),
74 );
75 assert!(mock.copy.called_with(expected_args));
76
77 let err = CloneableError {
78 kind: ErrorKind::NotFound,
79 description: "test",
80 };
81 mock.copy.return_err(err);
82
83 let result = copy_to_all(&mock, "from", &["to"]);
84
85 assert!(result.iter().all(|res| res.is_err()));
86}