You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.1 KiB
81 lines
2.1 KiB
use futures::stream::BoxStream;
|
|
use std::{fs, io, path, pin};
|
|
|
|
pub fn open_file(path: &path::Path) -> io::Result<Option<fs::File>> {
|
|
match fs::File::open(path) {
|
|
Ok(file) => Ok(Some(file)),
|
|
Err(err) => match err.kind() {
|
|
io::ErrorKind::NotFound => Ok(None),
|
|
_ => Err(err),
|
|
},
|
|
}
|
|
}
|
|
|
|
#[derive(thiserror::Error, Debug)]
|
|
pub enum ParseFileError<ParseError> {
|
|
#[error("io error: {0}")]
|
|
IO(io::Error),
|
|
|
|
#[error("parse error")]
|
|
FromStr(ParseError),
|
|
}
|
|
|
|
pub fn parse_file<T: std::str::FromStr>(
|
|
path: &path::Path,
|
|
) -> Result<Option<T>, ParseFileError<T::Err>> {
|
|
match fs::read_to_string(path) {
|
|
Ok(s) => Ok(Some(s.parse().map_err(ParseFileError::FromStr)?)),
|
|
Err(err) => match err.kind() {
|
|
io::ErrorKind::NotFound => Ok(None),
|
|
_ => Err(ParseFileError::IO(err)),
|
|
},
|
|
}
|
|
}
|
|
|
|
pub struct BoxByteStream(BoxStream<'static, io::Result<bytes::Bytes>>);
|
|
|
|
impl BoxByteStream {
|
|
pub fn from_stream<S>(s: S) -> Self
|
|
where
|
|
S: futures::stream::Stream<Item = std::io::Result<bytes::Bytes>> + Send + 'static,
|
|
{
|
|
Self(Box::into_pin(Box::new(s)))
|
|
}
|
|
|
|
pub fn from_async_read<R>(r: R) -> Self
|
|
where
|
|
R: tokio::io::AsyncRead + Send + 'static,
|
|
{
|
|
Self::from_stream(tokio_util::io::ReaderStream::new(r))
|
|
}
|
|
|
|
pub fn into_stream(
|
|
self,
|
|
) -> impl futures::stream::Stream<Item = std::io::Result<bytes::Bytes>> + Send + 'static {
|
|
self.0
|
|
}
|
|
|
|
pub fn into_async_read(self) -> impl tokio::io::AsyncRead + Send + 'static {
|
|
tokio_util::io::StreamReader::new(self.into_stream())
|
|
}
|
|
|
|
pub async fn read_to_end(self) -> io::Result<Vec<u8>> {
|
|
use tokio::io::AsyncReadExt;
|
|
let mut buf = Vec::<u8>::new();
|
|
self.into_async_read().read_to_end(&mut buf).await?;
|
|
Ok(buf)
|
|
}
|
|
}
|
|
|
|
pub type BoxFuture<'a, O> = pin::Pin<Box<dyn futures::Future<Output = O> + Send + 'a>>;
|
|
|
|
pub fn try_collect<I, V, E>(iter: I) -> Result<Vec<V>, E>
|
|
where
|
|
I: std::iter::Iterator<Item = Result<V, E>>,
|
|
{
|
|
let mut res = Vec::<V>::new();
|
|
for v in iter {
|
|
res.push(v?);
|
|
}
|
|
Ok(res)
|
|
}
|
|
|