zbus/abstractions/
file.rs

1//! Runtime-agnostic File I/O abstractions.
2//!
3//! Proving only specific API that we need internally.
4
5#[cfg(unix)]
6use std::fs::Metadata;
7use std::{
8    io::Result,
9    path::Path,
10    pin::Pin,
11    task::{Context, Poll},
12};
13
14use futures_core::Stream;
15
16#[cfg(not(feature = "tokio"))]
17#[derive(Debug)]
18pub struct FileLines(futures_util::io::Lines<futures_util::io::BufReader<async_fs::File>>);
19#[cfg(feature = "tokio")]
20#[derive(Debug)]
21pub struct FileLines(tokio::io::Lines<tokio::io::BufReader<tokio::fs::File>>);
22
23impl 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
45impl 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(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)]
70pub 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}