ayaka_bindings/
fs.rs

1use crate::import;
2use ayaka_bindings_types::{FileMetadata, FileSeekFrom};
3use std::io::{Read, Result, Seek, SeekFrom, Write};
4use vfs::{error::VfsErrorKind, *};
5
6#[import("fs")]
7extern "C" {
8    fn __read_dir(path: &str) -> Option<Vec<String>>;
9    fn __metadata(path: &str) -> Option<FileMetadata>;
10    fn __exists(path: &str) -> bool;
11
12    fn __open_file(path: &str) -> Option<u64>;
13    fn __close_file(fd: u64);
14
15    fn __file_read(fd: u64, ptr: i32, len: i32) -> Option<usize>;
16    fn __file_seek(fd: u64, pos: FileSeekFrom) -> Option<u64>;
17}
18
19#[derive(Debug, Default)]
20pub struct HostFS;
21
22impl FileSystem for HostFS {
23    fn read_dir(&self, path: &str) -> VfsResult<Box<dyn Iterator<Item = String> + Send>> {
24        match __read_dir(path) {
25            Some(paths) => Ok(Box::new(paths.into_iter())),
26            None => Err(VfsErrorKind::FileNotFound.into()),
27        }
28    }
29
30    fn create_dir(&self, _path: &str) -> VfsResult<()> {
31        Err(VfsErrorKind::NotSupported.into())
32    }
33
34    fn open_file(&self, path: &str) -> VfsResult<Box<dyn SeekAndRead + Send>> {
35        match __open_file(path) {
36            Some(fd) => Ok(Box::new(HostFile { fd })),
37            None => Err(VfsErrorKind::FileNotFound.into()),
38        }
39    }
40
41    fn create_file(&self, _path: &str) -> VfsResult<Box<dyn Write + Send>> {
42        Err(VfsErrorKind::NotSupported.into())
43    }
44
45    fn append_file(&self, _path: &str) -> VfsResult<Box<dyn Write + Send>> {
46        Err(VfsErrorKind::NotSupported.into())
47    }
48
49    fn metadata(&self, path: &str) -> VfsResult<VfsMetadata> {
50        match __metadata(path) {
51            Some(meta) => Ok(meta.into()),
52            None => Err(VfsErrorKind::FileNotFound.into()),
53        }
54    }
55
56    fn exists(&self, path: &str) -> VfsResult<bool> {
57        Ok(__exists(path))
58    }
59
60    fn remove_file(&self, _path: &str) -> VfsResult<()> {
61        Err(VfsErrorKind::NotSupported.into())
62    }
63
64    fn remove_dir(&self, _path: &str) -> VfsResult<()> {
65        Err(VfsErrorKind::NotSupported.into())
66    }
67}
68
69#[derive(Debug)]
70struct HostFile {
71    fd: u64,
72}
73
74impl Read for HostFile {
75    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
76        __file_read(self.fd, buf.as_mut_ptr() as _, buf.len() as _)
77            .ok_or_else(|| std::io::ErrorKind::NotFound.into())
78    }
79}
80
81impl Seek for HostFile {
82    fn seek(&mut self, pos: SeekFrom) -> Result<u64> {
83        __file_seek(self.fd, pos.into()).ok_or_else(|| std::io::ErrorKind::NotFound.into())
84    }
85}
86
87impl Drop for HostFile {
88    fn drop(&mut self) {
89        __close_file(self.fd)
90    }
91}