1 use serde::de::DeserializeOwned;
2 use serde::Serialize;
3 use std::ffi::OsStr;
4 use std::fs::{self, File};
5 use std::io::Read;
6 use std::path::Path;
7 use walkdir::{DirEntry, WalkDir};
8 
9 use crate::error::{Error, Result};
10 use crate::report::BenchmarkId;
11 
load<A, P: ?Sized>(path: &P) -> Result<A> where A: DeserializeOwned, P: AsRef<Path>,12 pub fn load<A, P: ?Sized>(path: &P) -> Result<A>
13 where
14     A: DeserializeOwned,
15     P: AsRef<Path>,
16 {
17     let path = path.as_ref();
18     let mut f = File::open(path).map_err(|inner| Error::AccessError {
19         inner,
20         path: path.to_owned(),
21     })?;
22     let mut string = String::new();
23     let _ = f.read_to_string(&mut string);
24     let result: A = serde_json::from_str(string.as_str()).map_err(|inner| Error::SerdeError {
25         inner,
26         path: path.to_owned(),
27     })?;
28 
29     Ok(result)
30 }
31 
is_dir<P>(path: &P) -> bool where P: AsRef<Path>,32 pub fn is_dir<P>(path: &P) -> bool
33 where
34     P: AsRef<Path>,
35 {
36     let path: &Path = path.as_ref();
37     path.is_dir()
38 }
39 
mkdirp<P>(path: &P) -> Result<()> where P: AsRef<Path>,40 pub fn mkdirp<P>(path: &P) -> Result<()>
41 where
42     P: AsRef<Path>,
43 {
44     fs::create_dir_all(path.as_ref()).map_err(|inner| Error::AccessError {
45         inner,
46         path: path.as_ref().to_owned(),
47     })?;
48     Ok(())
49 }
50 
cp(from: &Path, to: &Path) -> Result<()>51 pub fn cp(from: &Path, to: &Path) -> Result<()> {
52     fs::copy(from, to).map_err(|inner| Error::CopyError {
53         inner,
54         from: from.to_owned(),
55         to: to.to_owned(),
56     })?;
57     Ok(())
58 }
59 
save<D, P>(data: &D, path: &P) -> Result<()> where D: Serialize, P: AsRef<Path>,60 pub fn save<D, P>(data: &D, path: &P) -> Result<()>
61 where
62     D: Serialize,
63     P: AsRef<Path>,
64 {
65     let buf = serde_json::to_string(&data).map_err(|inner| Error::SerdeError {
66         path: path.as_ref().to_owned(),
67         inner,
68     })?;
69     save_string(&buf, path)
70 }
71 
save_string<P>(data: &str, path: &P) -> Result<()> where P: AsRef<Path>,72 pub fn save_string<P>(data: &str, path: &P) -> Result<()>
73 where
74     P: AsRef<Path>,
75 {
76     use std::io::Write;
77 
78     File::create(path)
79         .and_then(|mut f| f.write_all(data.as_bytes()))
80         .map_err(|inner| Error::AccessError {
81             inner,
82             path: path.as_ref().to_owned(),
83         })?;
84 
85     Ok(())
86 }
87 
list_existing_benchmarks<P>(directory: &P) -> Result<Vec<BenchmarkId>> where P: AsRef<Path>,88 pub fn list_existing_benchmarks<P>(directory: &P) -> Result<Vec<BenchmarkId>>
89 where
90     P: AsRef<Path>,
91 {
92     fn is_benchmark(entry: &DirEntry) -> bool {
93         // Look for benchmark.json files inside folders named "new" (because we want to ignore
94         // the baselines)
95         entry.file_name() == OsStr::new("benchmark.json")
96             && entry.path().parent().unwrap().file_name().unwrap() == OsStr::new("new")
97     }
98 
99     let mut ids = vec![];
100 
101     for entry in WalkDir::new(directory)
102         .into_iter()
103         // Ignore errors.
104         .filter_map(::std::result::Result::ok)
105         .filter(is_benchmark)
106     {
107         let id: BenchmarkId = load(entry.path())?;
108         ids.push(id);
109     }
110 
111     Ok(ids)
112 }
113