// SPDX-License-Identifier: MPL-2.0 //! VFS components pub use access_mode::AccessMode; pub use channel::{Channel, Consumer, Producer}; pub use creation_flags::CreationFlags; pub use dirent_visitor::DirentVisitor; pub use direntry_vec::DirEntryVecExt; pub use falloc_mode::FallocMode; pub use file_creation_mask::FileCreationMask; pub use fs::{FileSystem, FsFlags, SuperBlock}; pub use inode::{Inode, InodeMode, InodeType, Metadata}; pub use ioctl::IoctlCmd; pub use page_cache::{PageCache, PageCacheBackend}; pub use random_test::{generate_random_operation, new_fs_in_memory}; pub use status_flags::StatusFlags; mod access_mode; mod channel; mod creation_flags; mod dirent_visitor; mod direntry_vec; mod falloc_mode; mod file_creation_mask; mod fs; mod inode; mod ioctl; mod page_cache; mod random_test; mod status_flags; use crate::prelude::*; #[derive(Copy, PartialEq, Eq, Clone, Debug)] pub enum SeekFrom { Start(usize), End(isize), Current(isize), } /// Maximum bytes in a path pub const PATH_MAX: usize = 4096; /// Maximum bytes in a file name pub const NAME_MAX: usize = 255; /// The upper limit for resolving symbolic links pub const SYMLINKS_MAX: usize = 40; pub type CStr256 = FixedCStr<256>; pub type Str16 = FixedStr<16>; pub type Str64 = FixedStr<64>; /// An owned C-compatible string with a fixed capacity of `N`. /// /// The string is terminated with a null byte. #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Pod)] pub struct FixedCStr([u8; N]); impl FixedCStr { pub fn len(&self) -> usize { self.0.iter().position(|&b| b == 0).unwrap() } pub fn is_empty(&self) -> bool { self.len() == 0 } pub fn as_str(&self) -> Result<&str> { Ok(alloc::str::from_utf8(self.as_bytes())?) } pub fn as_cstr(&self) -> Result<&CStr> { Ok(CStr::from_bytes_with_nul(self.as_bytes_with_nul())?) } pub fn as_bytes(&self) -> &[u8] { &self.0[0..self.len()] } pub fn as_bytes_with_nul(&self) -> &[u8] { &self.0[0..=self.len()] } } impl<'a, const N: usize> From<&'a [u8]> for FixedCStr { fn from(bytes: &'a [u8]) -> Self { assert!(N > 0); let mut inner = [0u8; N]; let len = { let mut nul_byte_idx = match bytes.iter().position(|&b| b == 0) { Some(idx) => idx, None => bytes.len(), }; if nul_byte_idx >= N { nul_byte_idx = N - 1; } nul_byte_idx }; inner[0..len].copy_from_slice(&bytes[0..len]); Self(inner) } } impl<'a, const N: usize> From<&'a str> for FixedCStr { fn from(string: &'a str) -> Self { let bytes = string.as_bytes(); Self::from(bytes) } } impl<'a, const N: usize> From<&'a CStr> for FixedCStr { fn from(cstr: &'a CStr) -> Self { let bytes = cstr.to_bytes_with_nul(); Self::from(bytes) } } impl Default for FixedCStr { fn default() -> Self { Self([0u8; N]) } } impl Debug for FixedCStr { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self.as_cstr() { Ok(cstr) => write!(f, "{:?}", cstr), Err(_) => write!(f, "{:?}", self.as_bytes()), } } } /// An owned string with a fixed capacity of `N`. #[repr(C)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Pod)] pub struct FixedStr([u8; N]); impl FixedStr { pub fn len(&self) -> usize { self.0.iter().position(|&b| b == 0).unwrap_or(N) } pub fn is_empty(&self) -> bool { self.len() == 0 } pub fn as_str(&self) -> Result<&str> { Ok(alloc::str::from_utf8(self.as_bytes())?) } pub fn as_bytes(&self) -> &[u8] { &self.0[0..self.len()] } } impl<'a, const N: usize> From<&'a [u8]> for FixedStr { fn from(bytes: &'a [u8]) -> Self { let mut inner = [0u8; N]; let len = { let mut nul_byte_idx = match bytes.iter().position(|&b| b == 0) { Some(idx) => idx, None => bytes.len(), }; if nul_byte_idx > N { nul_byte_idx = N; } nul_byte_idx }; inner[0..len].copy_from_slice(&bytes[0..len]); Self(inner) } } impl<'a, const N: usize> From<&'a str> for FixedStr { fn from(string: &'a str) -> Self { let bytes = string.as_bytes(); Self::from(bytes) } } impl Default for FixedStr { fn default() -> Self { Self([0u8; N]) } } impl Debug for FixedStr { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { match self.as_str() { Ok(string) => write!(f, "{}", string), Err(_) => write!(f, "{:?}", self.as_bytes()), } } }