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}