cargo_lambda_metadata/fs/copy.rs
1// Code adapted from https://github.com/rust-lang/rustup
2
3// LICENSE:
4// Copyright (c) 2016 The Rust Project Developers
5//
6// Permission is hereby granted, free of charge, to any
7// person obtaining a copy of this software and associated
8// documentation files (the "Software"), to deal in the
9// Software without restriction, including without
10// limitation the rights to use, copy, modify, merge,
11// publish, distribute, sublicense, and/or sell copies of
12// the Software, and to permit persons to whom the Software
13// is furnished to do so, subject to the following
14// conditions:
15//
16// The above copyright notice and this permission notice
17// shall be included in all copies or substantial portions
18// of the Software.
19//
20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
22// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
24// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
27// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28// DEALINGS IN THE SOFTWARE.
29//
30
31use std::{fs, io, path::Path};
32
33pub fn copy_and_replace<P, Q>(from: P, to: Q) -> io::Result<()>
34where
35 P: AsRef<Path>,
36 Q: AsRef<Path>,
37{
38 copy_and_delete(from, to, true)
39}
40
41pub fn copy_without_replace<P, Q>(from: P, to: Q) -> io::Result<()>
42where
43 P: AsRef<Path>,
44 Q: AsRef<Path>,
45{
46 copy_and_delete(from, to, false)
47}
48
49fn copy_and_delete<P, Q>(from: P, to: Q, replace: bool) -> io::Result<()>
50where
51 P: AsRef<Path>,
52 Q: AsRef<Path>,
53{
54 let from = from.as_ref();
55 if from.is_dir() {
56 return copy_dir(from, to, replace).and(remove_dir_all::remove_dir_all(from));
57 } else if replace || !to.as_ref().exists() {
58 fs::copy(from, to)?;
59 }
60
61 if replace {
62 fs::remove_file(from)?;
63 }
64
65 Ok(())
66}
67
68fn copy_dir<P, Q>(from: P, to: Q, replace: bool) -> io::Result<()>
69where
70 P: AsRef<Path>,
71 Q: AsRef<Path>,
72{
73 fs::create_dir_all(&to)?;
74 for entry in from.as_ref().read_dir()? {
75 let entry = entry?;
76 let kind = entry.file_type()?;
77 let from = entry.path();
78
79 let to = to.as_ref().join(entry.file_name());
80 if kind.is_dir() {
81 copy_dir(&from, &to, replace)?;
82 } else if replace || !to.exists() {
83 fs::copy(&from, &to)?;
84 }
85 }
86 Ok(())
87}