blob: d1b0b70474b6d68993586e377e13168fe48a3e08 [file] [log] [blame]
David Tolnay0d85ccd2020-08-30 20:18:13 -07001#![allow(dead_code)]
2
3use std::error::Error as StdError;
4use std::fmt::{self, Display};
5use std::io;
6use std::path::{Path, PathBuf};
7
8type Result<T> = std::result::Result<T, Error>;
9
10#[derive(Debug)]
11pub(crate) struct Error {
12 source: io::Error,
13 message: String,
14}
15
16impl Display for Error {
17 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
18 formatter.write_str(&self.message)
19 }
20}
21
22impl StdError for Error {
23 fn source(&self) -> Option<&(dyn StdError + 'static)> {
24 Some(&self.source)
25 }
26}
27
28macro_rules! err {
29 ($io_error:expr, $fmt:expr $(, $path:expr)* $(,)?) => {
30 Err(Error {
31 source: $io_error,
32 message: format!($fmt $(, $path.display())*),
33 })
34 }
35}
36
37pub(crate) fn canonicalize(path: impl AsRef<Path>) -> Result<PathBuf> {
38 let path = path.as_ref();
39 match std::fs::canonicalize(path) {
40 Ok(string) => Ok(string),
41 Err(e) => err!(e, "Unable to canonicalize path: `{}`", path),
42 }
43}
44
45pub(crate) fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64> {
46 let from = from.as_ref();
47 let to = to.as_ref();
48 match std::fs::copy(from, to) {
49 Ok(n) => Ok(n),
50 Err(e) => err!(e, "Failed to copy `{}` -> `{}`", from, to),
51 }
52}
53
54pub(crate) fn create_dir_all(path: impl AsRef<Path>) -> Result<()> {
55 let path = path.as_ref();
56 match std::fs::create_dir_all(path) {
57 Ok(()) => Ok(()),
58 Err(e) => err!(e, "Failed to create directory `{}`", path),
59 }
60}
61
62pub(crate) fn current_dir() -> Result<PathBuf> {
63 match std::env::current_dir() {
64 Ok(dir) => Ok(dir),
65 Err(e) => err!(e, "Failed to determine current directory"),
66 }
67}
68
David Tolnaydbff3c42020-08-31 00:41:53 -070069pub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> {
David Tolnay0d85ccd2020-08-30 20:18:13 -070070 let path = path.as_ref();
David Tolnaydbff3c42020-08-31 00:41:53 -070071 match std::fs::read(path) {
David Tolnay0d85ccd2020-08-30 20:18:13 -070072 Ok(string) => Ok(string),
73 Err(e) => err!(e, "Failed to read file `{}`", path),
74 }
75}
76
77pub(crate) fn remove_file(path: impl AsRef<Path>) -> Result<()> {
78 let path = path.as_ref();
79 match std::fs::remove_file(path) {
80 Ok(()) => Ok(()),
81 Err(e) => err!(e, "Failed to remove file `{}`", path),
82 }
83}
84
85#[cfg(unix)]
86pub(crate) fn symlink(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
87 let src = src.as_ref();
88 let dst = dst.as_ref();
89 match std::os::unix::fs::symlink(src, dst) {
90 Ok(()) => Ok(()),
91 Err(e) => err!(
92 e,
93 "Failed to create symlink `{}` pointing to `{}`",
94 dst,
95 src,
96 ),
97 }
98}
99
100#[cfg(windows)]
101pub(crate) fn symlink_file(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> Result<()> {
102 let src = src.as_ref();
103 let dst = dst.as_ref();
104 match std::os::windows::fs::symlink_file(src, dst) {
105 Ok(()) => Ok(()),
106 Err(e) => err!(
107 e,
108 "Failed to create symlink `{}` pointing to `{}`",
109 dst,
110 src,
111 ),
112 }
113}
114
115pub(crate) fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> {
116 let path = path.as_ref();
117 match std::fs::write(path, contents) {
118 Ok(()) => Ok(()),
119 Err(e) => err!(e, "Failed to write file `{}`", path),
120 }
121}