Skip to main content

safa_abi/
fs.rs

1//! VFS related ABI structures
2use core::ops::BitOr;
3
4use crate::consts;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7#[repr(u8)]
8pub enum FSObjectType {
9    File,
10    Directory,
11    Device,
12}
13
14// Keep in sync with kernel implementition in kernel::vfs::expose::FileAttr
15// The ABI version cannot be used directly in the kernel implementition
16#[derive(Clone, Debug, PartialEq, Eq)]
17#[repr(C)]
18pub struct FileAttr {
19    pub kind: FSObjectType,
20    pub size: usize,
21}
22
23impl FileAttr {
24    pub const fn new(kind: FSObjectType, size: usize) -> Self {
25        Self { kind, size }
26    }
27}
28
29// Keep in sync with kernel implementition in kernel::vfs::expose::DirEntry
30// The ABI version cannot be used directly in the kernel implementition
31#[derive(Clone, Debug, PartialEq, Eq)]
32#[repr(C)]
33pub struct DirEntry {
34    pub attrs: FileAttr,
35    pub name_length: usize,
36    pub name: [u8; consts::MAX_NAME_LENGTH],
37}
38
39impl DirEntry {
40    pub fn new(name: &str, attrs: FileAttr) -> Self {
41        let name_length = name.len().min(consts::MAX_NAME_LENGTH);
42        let mut name_bytes = [0u8; consts::MAX_NAME_LENGTH];
43        name_bytes[..name_length].copy_from_slice(name.as_bytes());
44        Self {
45            attrs,
46            name_length,
47            name: name_bytes,
48        }
49    }
50}
51
52/// Describes the options for opening a file or directory.
53#[derive(Debug, PartialEq, Eq, Clone, Copy)]
54#[repr(transparent)]
55pub struct OpenOptions(u8);
56
57impl BitOr for OpenOptions {
58    type Output = Self;
59
60    fn bitor(self, other: Self) -> Self {
61        Self(self.0 | other.0)
62    }
63}
64
65impl OpenOptions {
66    /// Open the file for writing.
67    pub const WRITE: Self = Self(1 << 0);
68    /// Open the file for reading.
69    pub const READ: Self = Self(1 << 1);
70    /// Create the file if it does not exist.
71    pub const CREATE_FILE: Self = Self(1 << 2);
72    /// Create the directory if it does not exist. (doesn't create parent directories)
73    pub const CREATE_DIRECTORY: Self = Self(1 << 3);
74    /// Truncate the file to zero length if it already exists.
75    pub const WRITE_TRUNCATE: Self = Self(1 << 4);
76    // no append because the user would provide the offset anyways
77
78    pub const fn from_bits(bits: u8) -> Self {
79        Self(bits)
80    }
81
82    pub const fn contains(self, other: Self) -> bool {
83        self.0 & other.0 != 0
84    }
85
86    pub const fn is_write(&self) -> bool {
87        self.contains(Self::WRITE)
88    }
89
90    pub const fn is_write_truncate(&self) -> bool {
91        self.contains(Self::WRITE_TRUNCATE)
92    }
93
94    pub const fn is_read(&self) -> bool {
95        self.contains(Self::READ)
96    }
97
98    pub const fn create_file(&self) -> bool {
99        self.contains(Self::CREATE_FILE)
100    }
101
102    pub const fn create_dir(&self) -> bool {
103        self.contains(Self::CREATE_DIRECTORY)
104    }
105}