1use std::{
2 io::Result,
3 path::{Path, PathBuf},
4};
5
6use bitflags::bitflags;
7
8bitflags! {
9 pub struct FileKind: u8 {
11 const IS_FILE = 1 << 0;
13 const IS_DIR = 1 << 1;
15 const IS_SYMLINK = 1 << 2;
17 }
18}
19
20pub trait FileSystem: Send + Sync {
22 fn read_to_string(&self, path: &Path) -> Result<String>;
24 fn kind(&self, path: &Path) -> FileKind;
26 fn read_link(&self, path: &Path) -> Result<PathBuf>;
28}
29
30#[cfg(not(target_arch = "wasm32"))]
32#[derive(Default)]
33pub struct OsFileSystem;
34
35#[cfg(not(target_arch = "wasm32"))]
36impl FileSystem for OsFileSystem {
37 fn read_to_string(&self, path: &Path) -> Result<String> {
38 std::fs::read_to_string(path)
39 }
40
41 fn kind(&self, path: &Path) -> FileKind {
42 let mut flags = FileKind::empty();
43
44 if let Ok(metadata) = path.symlink_metadata() {
48 if metadata.is_symlink() {
49 flags.set(FileKind::IS_SYMLINK, true);
50 if let Ok(metadata) = path.metadata() {
51 flags.set(FileKind::IS_FILE, metadata.is_file());
52 flags.set(FileKind::IS_DIR, metadata.is_dir());
53 }
54 } else {
55 flags.set(FileKind::IS_FILE, metadata.is_file());
56 flags.set(FileKind::IS_DIR, metadata.is_dir());
57 }
58 }
59
60 flags
61 }
62
63 fn read_link(&self, path: &Path) -> Result<PathBuf> {
64 path.read_link()
65 }
66}