| 1 | //! Runtime-agnostic File I/O abstractions. |
| 2 | //! |
| 3 | //! Proving only specific API that we need internally. |
| 4 | |
| 5 | #[cfg (unix)] |
| 6 | use std::fs::Metadata; |
| 7 | use std::{ |
| 8 | io::Result, |
| 9 | path::Path, |
| 10 | pin::Pin, |
| 11 | task::{Context, Poll}, |
| 12 | }; |
| 13 | |
| 14 | use futures_core::Stream; |
| 15 | |
| 16 | #[cfg (not(feature = "tokio" ))] |
| 17 | #[derive (Debug)] |
| 18 | pub struct FileLines(futures_util::io::Lines<futures_util::io::BufReader<async_fs::File>>); |
| 19 | #[cfg (feature = "tokio" )] |
| 20 | #[derive (Debug)] |
| 21 | pub struct FileLines(tokio::io::Lines<tokio::io::BufReader<tokio::fs::File>>); |
| 22 | |
| 23 | impl FileLines { |
| 24 | pub async fn open(path: impl AsRef<Path>) -> Result<Self> { |
| 25 | #[cfg (not(feature = "tokio" ))] |
| 26 | { |
| 27 | async_fs::File::open(path) |
| 28 | .await |
| 29 | .map(futures_util::io::BufReader::new) |
| 30 | .map(futures_util::AsyncBufReadExt::lines) |
| 31 | .map(Self) |
| 32 | } |
| 33 | |
| 34 | #[cfg (feature = "tokio" )] |
| 35 | { |
| 36 | tokio::fs::File::open(path) |
| 37 | .await |
| 38 | .map(tokio::io::BufReader::new) |
| 39 | .map(tokio::io::AsyncBufReadExt::lines) |
| 40 | .map(Self) |
| 41 | } |
| 42 | } |
| 43 | } |
| 44 | |
| 45 | impl Stream for FileLines { |
| 46 | type Item = Result<String>; |
| 47 | |
| 48 | fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { |
| 49 | #[cfg (not(feature = "tokio" ))] |
| 50 | { |
| 51 | Stream::poll_next(self:Pin::new(&mut self.get_mut().0), cx) |
| 52 | } |
| 53 | |
| 54 | #[cfg (feature = "tokio" )] |
| 55 | { |
| 56 | let fut = self.get_mut().0.next_line(); |
| 57 | futures_util::pin_mut!(fut); |
| 58 | std::future::Future::poll(Pin::new(&mut fut), cx).map(Result::transpose) |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | #[cfg (not(feature = "tokio" ))] |
| 63 | fn size_hint(&self) -> (usize, Option<usize>) { |
| 64 | self.0.size_hint() |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | // Not unix-specific itself but only used on unix. |
| 69 | #[cfg (unix)] |
| 70 | pub async fn metadata(path: impl AsRef<Path>) -> Result<Metadata> { |
| 71 | #[cfg (not(feature = "tokio" ))] |
| 72 | { |
| 73 | async_fs::metadata(path).await |
| 74 | } |
| 75 | |
| 76 | #[cfg (feature = "tokio" )] |
| 77 | { |
| 78 | tokio::fs::metadata(path).await |
| 79 | } |
| 80 | } |
| 81 | |