1use std::fs::File;
2use std::io::{Read, Write};
3use std::path::Path;
4use std::fs;
5
6use toml::Value;
7use walkdir::WalkDir;
8
9use errors::*;
10
11pub fn cp_r(src: &Path, dst: &Path) -> Result<()> {
12 for e in WalkDir::new(src) {
13 let e = e.chain_err(|| {
17 format!(
18 "intermittent IO error while iterating directory `{}`",
19 src.display()
20 )
21 })?;
22
23 let src_file = e.path();
24 let relative_path = src_file.strip_prefix(src).chain_err(|| {
25 format!(
26 "Could not retrieve relative path of child directory or \
27 file `{}` with regards to parent directory `{}`",
28 src_file.display(),
29 src.display()
30 )
31 })?;
32
33 let dst_file = dst.join(relative_path);
34 let metadata = e.metadata().chain_err(|| {
35 format!("Could not retrieve metadata of `{}`", e.path().display())
36 })?;
37
38 if metadata.is_dir() {
39 fs::create_dir_all(&dst_file).chain_err(|| {
41 format!("Could not create directory `{}`", dst_file.display())
42 })?;
43 } else {
44 fs::copy(&src_file, &dst_file).chain_err(|| {
46 format!(
47 "copying files from `{}` to `{}` failed",
48 src_file.display(),
49 dst_file.display()
50 )
51 })?;
52 };
53 }
54
55 Ok(())
56}
57
58pub fn mkdir(path: &Path) -> Result<()> {
59 fs::create_dir(path).chain_err(|| format!("couldn't create directory {}", path.display()))
60}
61
62pub fn parse(path: &Path) -> Result<Value> {
64 Ok(toml::from_str(&read(path)?)
65 .map_err(|_| format!("{} is not valid TOML", path.display()))?)
66}
67
68pub fn read(path: &Path) -> Result<String> {
69 let mut s = String::new();
70
71 let p = path.display();
72 File::open(path)
73 .chain_err(|| format!("couldn't open {}", p))?
74 .read_to_string(&mut s)
75 .chain_err(|| format!("couldn't read {}", p))?;
76
77 Ok(s)
78}
79
80pub fn search<'p>(mut path: &'p Path, file: &str) -> Option<&'p Path> {
82 loop {
83 if path.join(file).exists() {
84 return Some(path);
85 }
86
87 if let Some(p) = path.parent() {
88 path = p;
89 } else {
90 return None;
91 }
92 }
93}
94
95pub fn write(path: &Path, contents: &str) -> Result<()> {
96 let p = path.display();
97 File::create(path)
98 .chain_err(|| format!("couldn't open {}", p))?
99 .write_all(contents.as_bytes())
100 .chain_err(|| format!("couldn't write to {}", p))
101}