1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
extern crate glob; extern crate tempdir; use std::io::prelude::*; use std::{env, fmt, io, process, path, fs, iter}; pub fn empty<T, C: iter::FromIterator<T>>() -> C { iter::empty().collect() } pub fn tmpdir<S: AsRef<str>>(prefix: S) -> (tempdir::TempDir, String) { let tmp = tempdir::TempDir::new(prefix.as_ref()).unwrap_or_else(|err| panic!("tmpdir: failed to create temporary directory: {}", err)); let path = tmp.path().to_str().unwrap_or_else(|| panic!("tmpdir: path was not valid UTF-8")).to_owned(); return (tmp, path); } pub fn glob<P: AsRef<str>>(pattern: P) -> Vec<String> { match glob::glob(pattern.as_ref()) { Ok(matches) => matches .filter_map(Result::ok) .filter_map(|p| p.as_path().to_str().map(str::to_owned)) .collect(), Err(err) => panic!("glob: error globbing: {}", err), } } pub fn touch<P: AsRef<path::Path>>(path: P) { if let Err(err) = fs::OpenOptions::new().create(true).append(true).open(path) { panic!("touch: {}", err) } } pub fn mkdir<P: AsRef<path::Path>>(path: P) { if let Err(err) = fs::create_dir(path) { panic!("mkdir: {}", err) } } pub fn rmdir<P: AsRef<path::Path>>(path: P) { if let Err(err) = fs::remove_dir(path) { panic!("rmdir: {}", err) } } pub fn rm<P: AsRef<path::Path>>(path: P) { if let Err(err) = fs::remove_file(path) { panic!("rm: {}", err); } } pub fn slurp<P: AsRef<path::Path>>(path: P) -> String { let mut file = fs::File::open(path).unwrap_or_else(|err| panic!("slurp {}", err)); let mut s = String::new(); if let Err(err) = file.read_to_string(&mut s) { panic!("slurp: {}", err) } s } pub fn read<P: AsRef<path::Path>>(path: P) -> Vec<u8> { let mut file = fs::File::open(path).unwrap_or_else(|err| panic!("read {}", err)); let mut v = vec![]; if let Err(err) = file.read_to_end(&mut v) { panic!("read: {}", err) } v } pub fn dump<P: AsRef<path::Path>, D: AsRef<[u8]>>(path: P, data: D) { let bytes = data.as_ref(); let count = bytes.len(); let mut file = fs::File::create(path).unwrap_or_else(|err| panic!("dump {}", err)); match file.write(bytes) { Err(err) => panic!("dump: {}", err), Ok(n) => if n != count { panic!("dump: only {} of {} bytes written", n, count); } } } pub fn cd<P: AsRef<path::Path>>(path: P) { if let Err(err) = env::set_current_dir(path) { panic!("cd: {}", err) } } pub fn cwd() -> String { match env::current_dir() { Ok(pathbuf) => pathbuf.to_str().unwrap_or_else(|| panic!("cwd: cwd was not a valid UTF-8 string")).to_string(), Err(err) => panic!("cwd: {}", err), } } pub fn can(command: &str) -> bool { let paths = match env::var_os("PATH") { Some(os_paths) => os_paths.to_str().unwrap_or_else(|| panic!("can: PATH environment variable is not valid UTF-8")).to_owned(), None => panic!("can: PATH environment variable is not set"), }; for path in paths.split(":") { let candidate = format!("{}/{}", path, command); if isfile(&candidate) { return true; } } false } pub fn isfile<P: AsRef<path::Path>>(path: P) -> bool { match fs::metadata(path) { Ok(metadata) => metadata.is_file(), Err(err) => { if let io::ErrorKind::NotFound = err.kind() { return false; }; panic!("isfile: could not retrieve metadata: {}", err); } } } pub fn isdir<P: AsRef<path::Path>>(path: P) -> bool { match fs::metadata(path) { Ok(metadata) => metadata.is_dir(), Err(err) => { if let io::ErrorKind::NotFound = err.kind() { return false; }; panic!("isfile: could not retrieve metadata: {}", err); } } } pub fn say(d: &fmt::Display) { println!("{}", d) } pub fn out(d: &fmt::Display) { if let Err(err) = write!(&mut io::stdout(), "{}", d) { panic!("warn: {}", err); } } pub fn err(d: &fmt::Display) { if let Err(err) = write!(&mut io::stderr(), "{}", d) { panic!("warn: {}", err); } } pub fn warn(d: &fmt::Display) { if let Err(err) = writeln!(&mut io::stderr(), "{}", d) { panic!("warn: {}", err); } } pub fn die(d: &fmt::Display) -> ! { warn(d); process::exit(-1) } #[macro_export] macro_rules! warn { ($($arg:tt)*) => {{ extern crate std; use std::io::prelude::*; if let Err(_) = writeln!(&mut std::io::stderr(), $($arg)*) { std::process::exit(-1); }; }}; } #[macro_export] macro_rules! die { ($($arg:tt)*) => {{ extern crate std; warn!($($arg)*); std::process::exit(-1) }}; } mod tests;