1use std::io;
5use std::path::Path;
6
7use crate::stats::CloneBackend;
8
9#[cfg(target_os = "macos")]
10mod apfs;
11#[cfg(any(target_os = "linux", target_os = "android", windows))]
12mod reflink;
13#[cfg(not(any(
14 target_os = "macos",
15 target_os = "linux",
16 target_os = "android",
17 windows
18)))]
19mod unsupported;
20
21pub trait BlockCloner {
23 fn backend(&self) -> CloneBackend;
25
26 fn clone_file(&self, source: &Path, destination: &Path) -> io::Result<()>;
28
29 fn clone_directory(&self, source: &Path, destination: &Path) -> io::Result<()>;
31
32 fn clones_directories(&self) -> bool;
34}
35
36pub fn for_this_platform() -> Box<dyn BlockCloner> {
38 #[cfg(target_os = "macos")]
39 {
40 Box::new(apfs::Clonefile)
41 }
42 #[cfg(any(target_os = "linux", target_os = "android"))]
43 {
44 Box::new(reflink::Reflink::new(CloneBackend::Ficlone))
45 }
46 #[cfg(windows)]
47 {
48 Box::new(reflink::Reflink::new(CloneBackend::Refs))
49 }
50 #[cfg(not(any(
51 target_os = "macos",
52 target_os = "linux",
53 target_os = "android",
54 windows
55 )))]
56 {
57 Box::new(unsupported::Unsupported)
58 }
59}