safa_abi/raw/
io.rs

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