use std::fs;
use std::io::{self, BufRead};
use std::path::Path;
use std::str::FromStr;
use crate::prelude::*;
pub fn path_exists<T>(path: T) -> impl Future<Output = bool>
where
T: AsRef<Path> + Send + 'static,
{
future::ready(path.as_ref().exists())
}
pub fn read_to_string<T>(path: T) -> impl Future<Output = Result<String>>
where
T: AsRef<Path> + Send + 'static,
{
let res = fs::read_to_string(path).map_err(From::from);
future::ready(res)
}
pub fn read_into<T, R, E>(path: T) -> impl Future<Output = Result<R>>
where
T: AsRef<Path> + Send + 'static,
R: FromStr<Err = E>,
Error: From<E>,
{
read_to_string(path).then(|try_content| match try_content {
Ok(content) => future::ready(R::from_str(&content).map_err(Error::from)),
Err(e) => future::err(e),
})
}
pub fn read_lines<T>(path: T) -> impl TryStream<Ok = String, Error = Error>
where
T: AsRef<Path> + Send + 'static,
{
future::ready(fs::File::open(path))
.map_err(Error::from)
.map_ok(|file| {
let reader = io::BufReader::new(file);
stream::iter(reader.lines()).map_err(Error::from)
})
.try_flatten_stream()
}
pub fn read_lines_into<T, R, E>(path: T) -> impl TryStream<Ok = R, Error = Error>
where
T: AsRef<Path> + Send + 'static,
R: FromStr<Err = E>,
Error: From<E>,
{
read_lines(path).into_stream().then(|result| {
let res = result.and_then(|line| R::from_str(&line).map_err(Error::from));
future::ready(res)
})
}
pub fn read_first_line<T>(path: T) -> impl TryFuture<Ok = String, Error = Error>
where
T: AsRef<Path> + Send + 'static,
{
read_lines(path)
.into_stream()
.into_future()
.map(|(try_line, _)| match try_line {
Some(Ok(line)) => Ok(line),
Some(Err(e)) => Err(e),
None => Err(Error::missing_entity("line")),
})
}
pub fn read_dir<T>(path: T) -> impl TryStream<Ok = fs::DirEntry, Error = Error>
where
T: AsRef<Path> + Send + 'static,
{
future::ready(fs::read_dir(path))
.map_err(Error::from)
.map_ok(|iter| stream::iter(iter).map_err(Error::from))
.try_flatten_stream()
}