munyo/file_io/
mod.rs

1//! Utilities for File IO.
2
3pub(crate) mod concurrent;
4use std::path::PathBuf;
5
6use async_channel::TryRecvError;
7
8/// File's path and parsed items.
9#[derive(Debug, Clone, PartialEq)]
10pub struct Data<T> {
11    /// Path of the source file.
12    pub path: PathBuf,
13    /// Processed data of the source file.
14    pub items: Vec<T>,
15}
16
17impl<T> Data<T> {
18    pub(crate) fn new(path: PathBuf, items: Vec<T>) -> Self {
19        Self { path, items }
20    }
21}
22
23type AsyncReceiver<T> = async_channel::Receiver<T>;
24
25/// Finished items will be sent over this Receiver asynchronously.
26pub struct Receiver<T> {
27    /// Receiver of async_channel. It implements futures::Stream, so you can use futures::StreamExt utility methods.
28    pub receiver: AsyncReceiver<T>,
29}
30
31impl<T> Receiver<T> {
32    pub(crate) fn new(receiver: AsyncReceiver<T>) -> Receiver<T> {
33        Receiver { receiver }
34    }
35    /// Wait for the item to be ready and receive it.
36    /// Return None if all items are already received.
37    pub fn recv_blocking(&self) -> Option<T> {
38        self.receiver.recv_blocking().ok()
39    }
40    /// Receive an item if it's ready. Return None if it's not ready.
41    /// Return Some(None) if all items are already received.
42    pub fn try_recv(&self) -> Option<Option<T>> {
43        match self.receiver.try_recv() {
44            Ok(t) => Some(Some(t)),
45            Err(TryRecvError::Closed) => Some(None),
46            Err(TryRecvError::Empty) => None,
47        }
48    }
49    /// Receive an item asynchronously. Return None if all items are already received.
50    ///
51    /// This only uses std::thread and async_channel, so I believe this async fn is runtime agnostic.
52    pub async fn recv_async(&self) -> Option<T> {
53        self.receiver.recv().await.ok()
54    }
55}