133d722a9Sopenharmony_ci#![allow(dead_code)] 233d722a9Sopenharmony_ci 333d722a9Sopenharmony_ciuse std::error::Error as StdError; 433d722a9Sopenharmony_ciuse std::fmt::{self, Display}; 533d722a9Sopenharmony_ciuse std::io::{self, Read}; 633d722a9Sopenharmony_ciuse std::path::{Path, PathBuf}; 733d722a9Sopenharmony_ci 833d722a9Sopenharmony_cipub(crate) type Result<T> = std::result::Result<T, Error>; 933d722a9Sopenharmony_ci 1033d722a9Sopenharmony_ci#[derive(Debug)] 1133d722a9Sopenharmony_cipub(crate) struct Error { 1233d722a9Sopenharmony_ci source: Option<io::Error>, 1333d722a9Sopenharmony_ci message: String, 1433d722a9Sopenharmony_ci} 1533d722a9Sopenharmony_ci 1633d722a9Sopenharmony_ciimpl Error { 1733d722a9Sopenharmony_ci pub fn kind(&self) -> io::ErrorKind { 1833d722a9Sopenharmony_ci match &self.source { 1933d722a9Sopenharmony_ci Some(io_error) => io_error.kind(), 2033d722a9Sopenharmony_ci None => io::ErrorKind::Other, 2133d722a9Sopenharmony_ci } 2233d722a9Sopenharmony_ci } 2333d722a9Sopenharmony_ci} 2433d722a9Sopenharmony_ci 2533d722a9Sopenharmony_ciimpl Display for Error { 2633d722a9Sopenharmony_ci fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 2733d722a9Sopenharmony_ci formatter.write_str(&self.message) 2833d722a9Sopenharmony_ci } 2933d722a9Sopenharmony_ci} 3033d722a9Sopenharmony_ci 3133d722a9Sopenharmony_ciimpl StdError for Error { 3233d722a9Sopenharmony_ci fn source(&self) -> Option<&(dyn StdError + 'static)> { 3333d722a9Sopenharmony_ci let source = self.source.as_ref()?; 3433d722a9Sopenharmony_ci Some(source) 3533d722a9Sopenharmony_ci } 3633d722a9Sopenharmony_ci} 3733d722a9Sopenharmony_ci 3833d722a9Sopenharmony_cimacro_rules! err { 3933d722a9Sopenharmony_ci ($io_error:expr, $fmt:expr $(, $path:expr)* $(,)?) => { 4033d722a9Sopenharmony_ci Err(Error { 4133d722a9Sopenharmony_ci source: Option::from($io_error), 4233d722a9Sopenharmony_ci message: format!($fmt $(, $path.display())*), 4333d722a9Sopenharmony_ci }) 4433d722a9Sopenharmony_ci } 4533d722a9Sopenharmony_ci} 4633d722a9Sopenharmony_ci 4733d722a9Sopenharmony_cipub(crate) fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<u64> { 4833d722a9Sopenharmony_ci let from = from.as_ref(); 4933d722a9Sopenharmony_ci let to = to.as_ref(); 5033d722a9Sopenharmony_ci match std::fs::copy(from, to) { 5133d722a9Sopenharmony_ci Ok(n) => Ok(n), 5233d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to copy `{}` -> `{}`", from, to), 5333d722a9Sopenharmony_ci } 5433d722a9Sopenharmony_ci} 5533d722a9Sopenharmony_ci 5633d722a9Sopenharmony_cipub(crate) fn create_dir_all(path: impl AsRef<Path>) -> Result<()> { 5733d722a9Sopenharmony_ci let path = path.as_ref(); 5833d722a9Sopenharmony_ci match std::fs::create_dir_all(path) { 5933d722a9Sopenharmony_ci Ok(()) => Ok(()), 6033d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to create directory `{}`", path), 6133d722a9Sopenharmony_ci } 6233d722a9Sopenharmony_ci} 6333d722a9Sopenharmony_ci 6433d722a9Sopenharmony_cipub(crate) fn current_dir() -> Result<PathBuf> { 6533d722a9Sopenharmony_ci match std::env::current_dir() { 6633d722a9Sopenharmony_ci Ok(dir) => Ok(dir), 6733d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to determine current directory"), 6833d722a9Sopenharmony_ci } 6933d722a9Sopenharmony_ci} 7033d722a9Sopenharmony_ci 7133d722a9Sopenharmony_cipub(crate) fn exists(path: impl AsRef<Path>) -> bool { 7233d722a9Sopenharmony_ci let path = path.as_ref(); 7333d722a9Sopenharmony_ci // If path is a symlink, this returns true, regardless of whether the 7433d722a9Sopenharmony_ci // symlink points to a path that exists. 7533d722a9Sopenharmony_ci std::fs::symlink_metadata(path).is_ok() 7633d722a9Sopenharmony_ci} 7733d722a9Sopenharmony_ci 7833d722a9Sopenharmony_cipub(crate) fn read(path: impl AsRef<Path>) -> Result<Vec<u8>> { 7933d722a9Sopenharmony_ci let path = path.as_ref(); 8033d722a9Sopenharmony_ci match std::fs::read(path) { 8133d722a9Sopenharmony_ci Ok(string) => Ok(string), 8233d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to read file `{}`", path), 8333d722a9Sopenharmony_ci } 8433d722a9Sopenharmony_ci} 8533d722a9Sopenharmony_ci 8633d722a9Sopenharmony_cipub(crate) fn read_stdin() -> Result<Vec<u8>> { 8733d722a9Sopenharmony_ci let mut bytes = Vec::new(); 8833d722a9Sopenharmony_ci match io::stdin().read_to_end(&mut bytes) { 8933d722a9Sopenharmony_ci Ok(_len) => Ok(bytes), 9033d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to read input from stdin"), 9133d722a9Sopenharmony_ci } 9233d722a9Sopenharmony_ci} 9333d722a9Sopenharmony_ci 9433d722a9Sopenharmony_cipub(crate) fn remove_file(path: impl AsRef<Path>) -> Result<()> { 9533d722a9Sopenharmony_ci let path = path.as_ref(); 9633d722a9Sopenharmony_ci match std::fs::remove_file(path) { 9733d722a9Sopenharmony_ci Ok(()) => Ok(()), 9833d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to remove file `{}`", path), 9933d722a9Sopenharmony_ci } 10033d722a9Sopenharmony_ci} 10133d722a9Sopenharmony_ci 10233d722a9Sopenharmony_cipub(crate) fn remove_dir(path: impl AsRef<Path>) -> Result<()> { 10333d722a9Sopenharmony_ci let path = path.as_ref(); 10433d722a9Sopenharmony_ci match std::fs::remove_dir(path) { 10533d722a9Sopenharmony_ci Ok(()) => Ok(()), 10633d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to remove directory `{}`", path), 10733d722a9Sopenharmony_ci } 10833d722a9Sopenharmony_ci} 10933d722a9Sopenharmony_ci 11033d722a9Sopenharmony_cifn symlink<'a>( 11133d722a9Sopenharmony_ci original: &'a Path, 11233d722a9Sopenharmony_ci link: &'a Path, 11333d722a9Sopenharmony_ci fun: fn(&'a Path, &'a Path) -> io::Result<()>, 11433d722a9Sopenharmony_ci) -> Result<()> { 11533d722a9Sopenharmony_ci match fun(original, link) { 11633d722a9Sopenharmony_ci Ok(()) => Ok(()), 11733d722a9Sopenharmony_ci Err(e) => err!( 11833d722a9Sopenharmony_ci e, 11933d722a9Sopenharmony_ci "Failed to create symlink `{}` pointing to `{}`", 12033d722a9Sopenharmony_ci link, 12133d722a9Sopenharmony_ci original, 12233d722a9Sopenharmony_ci ), 12333d722a9Sopenharmony_ci } 12433d722a9Sopenharmony_ci} 12533d722a9Sopenharmony_ci 12633d722a9Sopenharmony_cipub(crate) fn symlink_fail(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { 12733d722a9Sopenharmony_ci err!( 12833d722a9Sopenharmony_ci None, 12933d722a9Sopenharmony_ci "Failed to create symlink `{}` pointing to `{}`", 13033d722a9Sopenharmony_ci link.as_ref(), 13133d722a9Sopenharmony_ci original.as_ref(), 13233d722a9Sopenharmony_ci ) 13333d722a9Sopenharmony_ci} 13433d722a9Sopenharmony_ci 13533d722a9Sopenharmony_ci#[cfg(unix)] 13633d722a9Sopenharmony_ci#[allow(unused_imports)] 13733d722a9Sopenharmony_cipub(crate) use self::symlink_file as symlink_dir; 13833d722a9Sopenharmony_ci 13933d722a9Sopenharmony_ci#[cfg(not(any(unix, windows)))] 14033d722a9Sopenharmony_ci#[allow(unused_imports)] 14133d722a9Sopenharmony_cipub(crate) use self::symlink_fail as symlink_dir; 14233d722a9Sopenharmony_ci 14333d722a9Sopenharmony_ci#[cfg(unix)] 14433d722a9Sopenharmony_cipub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { 14533d722a9Sopenharmony_ci symlink(original.as_ref(), link.as_ref(), std::os::unix::fs::symlink) 14633d722a9Sopenharmony_ci} 14733d722a9Sopenharmony_ci 14833d722a9Sopenharmony_ci#[cfg(windows)] 14933d722a9Sopenharmony_cipub(crate) fn symlink_file(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { 15033d722a9Sopenharmony_ci symlink( 15133d722a9Sopenharmony_ci original.as_ref(), 15233d722a9Sopenharmony_ci link.as_ref(), 15333d722a9Sopenharmony_ci std::os::windows::fs::symlink_file, 15433d722a9Sopenharmony_ci ) 15533d722a9Sopenharmony_ci} 15633d722a9Sopenharmony_ci 15733d722a9Sopenharmony_ci#[cfg(windows)] 15833d722a9Sopenharmony_cipub(crate) fn symlink_dir(original: impl AsRef<Path>, link: impl AsRef<Path>) -> Result<()> { 15933d722a9Sopenharmony_ci symlink( 16033d722a9Sopenharmony_ci original.as_ref(), 16133d722a9Sopenharmony_ci link.as_ref(), 16233d722a9Sopenharmony_ci std::os::windows::fs::symlink_dir, 16333d722a9Sopenharmony_ci ) 16433d722a9Sopenharmony_ci} 16533d722a9Sopenharmony_ci 16633d722a9Sopenharmony_cipub(crate) fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> Result<()> { 16733d722a9Sopenharmony_ci let path = path.as_ref(); 16833d722a9Sopenharmony_ci match std::fs::write(path, contents) { 16933d722a9Sopenharmony_ci Ok(()) => Ok(()), 17033d722a9Sopenharmony_ci Err(e) => err!(e, "Failed to write file `{}`", path), 17133d722a9Sopenharmony_ci } 17233d722a9Sopenharmony_ci} 173