Skip to main content

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