use std::convert::AsRef;
use std::iter::IntoIterator;
use std::path::Path;
use std::io::{Result as IoResult, Error as IoError};
use std::io::{Write, Read, BufRead, Lines, BufReader, BufWriter};
use std::fs::{OpenOptions, File, remove_file};
use std::fs::copy as fs_copy;
#[cfg(windows)]
const LINE_SEP: &'static [u8] = b"\r\n";
#[cfg(not(windows))]
const LINE_SEP: &'static [u8] = b"\n";
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> IoResult<()> {
let file = try!(OpenOptions::new().write(true).create(true).truncate(true).open(path));
let mut file = BufWriter::new(file);
file.write_all(contents.as_ref())
}
pub fn write_lines<P: AsRef<Path>, I: IntoIterator<Item=B, IntoIter=A>, A: Iterator<Item=B>, B: AsRef<[u8]>>(path: P, lines: I) -> IoResult<()> {
let file = try!(OpenOptions::new().write(true).create(true).truncate(true).open(path));
let mut file = BufWriter::new(file);
for line in lines.into_iter() {
try!(file.write_all(line.as_ref()));
try!(file.write_all(LINE_SEP));
}
Ok(())
}
pub fn append<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> IoResult<()> {
let mut file = try!(OpenOptions::new().write(true).create(true).append(true).open(path));
file.write_all(contents.as_ref())
}
pub fn append_line<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> IoResult<()> {
let mut file = try!(OpenOptions::new().write(true).create(true).append(true).open(path));
try!(file.write_all(contents.as_ref()));
file.write_all(LINE_SEP)
}
pub fn read<P: AsRef<Path>>(path: P) -> IoResult<Vec<u8>> {
let file = try!(OpenOptions::new().read(true).open(path));
let mut file = BufReader::new(file);
let mut out = vec![];
try!(file.read_to_end(&mut out));
Ok(out)
}
pub fn read_string_utf8<P: AsRef<Path>>(path: P) -> IoResult<String> {
match read(path) {
Ok(bytes) => match String::from_utf8(bytes) {
Ok(s) => Ok(s),
Err(e) => Err(IoError::new(::std::io::ErrorKind::Other, e)),
},
Err(e) => Err(e)
}
}
pub fn read_string_utf8_lossy<P: AsRef<Path>>(path: P) -> IoResult<String> {
match read(path) {
Ok(bytes) => Ok(String::from_utf8_lossy(&bytes[..]).into_owned()),
Err(e) => Err(e)
}
}
pub fn read_lines<P: AsRef<Path>>(path: P) -> IoResult<Lines<BufReader<File>>> {
let file = try!(OpenOptions::new().read(true).open(path));
let file = BufReader::new(file);
Ok(file.lines())
}
pub fn exists<P: AsRef<Path>>(path: P) -> bool {
let path = path.as_ref();
path.is_file() && path.exists()
}
pub fn copy<Fp: AsRef<Path>, Tp: AsRef<Path>>(from: Fp, to: Tp) -> IoResult<()> {
fs_copy(from, to).map(|_| ())
}
pub fn remove<P: AsRef<Path>>(path: P) -> IoResult<()> {
remove_file(path)
}
pub fn has_extension<P: AsRef<Path>, S: AsRef<str>>(path: P, ext: S) -> bool {
path.as_ref().extension()
.and_then(|ext| ext.to_str())
.map(|provided_ext| provided_ext == ext.as_ref())
.unwrap_or(false)
}