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}