virtual_file_system/
directory.rs

1use core::mem::forget;
2
3use exported_file_system::{FileSystemOperations, StateFlags};
4use file_system::{Context, Entry, Flags, Path, Size};
5use task::TaskIdentifier;
6use task::block_on;
7
8use crate::{ItemStatic, Result, SynchronousDirectory, VirtualFileSystem, poll};
9
10pub struct Directory(SynchronousDirectory);
11
12impl Directory {
13    pub(crate) fn new(
14        directory: &'static dyn FileSystemOperations,
15        flags: Flags,
16        context: Context,
17    ) -> Self {
18        let flags = Flags::new(
19            flags.get_access(),
20            Some(flags.get_create()),
21            Some(flags.get_state().insert(StateFlags::NonBlocking)),
22        );
23
24        Self(SynchronousDirectory::new(directory, flags, context))
25    }
26
27    pub async fn create(
28        virtual_file_system: &VirtualFileSystem,
29        task: TaskIdentifier,
30        path: impl AsRef<Path>,
31    ) -> Result<()> {
32        virtual_file_system.create_directory(task, &path).await
33    }
34
35    pub async fn open(
36        virtual_file_system: &VirtualFileSystem,
37        task: TaskIdentifier,
38        path: impl AsRef<Path>,
39    ) -> Result<Self> {
40        virtual_file_system.open_directory(task, &path).await
41    }
42
43    pub async fn read(&mut self) -> Result<Option<Entry>> {
44        poll(|| self.0.read()).await
45    }
46
47    pub async fn get_position(&mut self) -> Result<Size> {
48        poll(|| self.0.get_position()).await
49    }
50
51    pub async fn set_position(&mut self, position: Size) -> Result<()> {
52        poll(|| self.0.set_position(position)).await
53    }
54
55    pub async fn rewind(&mut self) -> Result<()> {
56        poll(|| self.0.set_position(0)).await
57    }
58
59    pub async fn close(mut self, virtual_file_system: &VirtualFileSystem) -> Result<()> {
60        let result = virtual_file_system
61            .close(
62                &ItemStatic::Directory(self.0.directory),
63                &mut self.0.context,
64            )
65            .await;
66        forget(self.0);
67
68        result
69    }
70
71    pub fn into_synchronous_directory(self) -> SynchronousDirectory {
72        self.0
73    }
74}
75
76impl Iterator for Directory {
77    type Item = Entry;
78
79    fn next(&mut self) -> Option<Self::Item> {
80        block_on(self.read()).unwrap()
81    }
82}