use std::{cell::RefCell, collections::HashMap, ffi::OsString};
use fuser::{FileHandle, FileType as FuseFileType, INodeNo};
use nix::fcntl::OFlag;
use super::pool::IdPool;
use crate::{FileDiscriminant, FileId, RawFd};
impl FileDiscriminant {
pub(crate) fn to_fuse_file_type(self) -> fuser::FileType {
match self {
FileDiscriminant::Regular => fuser::FileType::RegularFile,
FileDiscriminant::Dir => fuser::FileType::Directory,
FileDiscriminant::Symlink => fuser::FileType::Symlink,
FileDiscriminant::Block => fuser::FileType::BlockDevice,
FileDiscriminant::Char => fuser::FileType::CharDevice,
FileDiscriminant::Pipe => fuser::FileType::NamedPipe,
}
}
}
#[derive(Debug, Clone)]
pub struct DirectoryEntry {
pub file_name: OsString,
pub file_type: FuseFileType,
pub inode: INodeNo,
}
#[derive(Debug)]
pub struct FileHandleState {
pub flags: OFlag,
pub position: u64,
pub file_id: FileId,
pub fd: RefCell<Option<RawFd>>,
}
#[derive(Debug)]
pub struct DirectoryHandleState {
pub entries: Vec<DirectoryEntry>,
}
#[derive(Debug)]
pub enum HandleState {
File(FileHandleState),
Directory(DirectoryHandleState),
}
#[derive(Debug, Default)]
pub struct HandleTable {
pool: IdPool,
state: HashMap<FileHandle, HandleState>,
}
impl HandleTable {
pub fn new() -> Self {
Self::default()
}
pub fn open(&mut self, state: HandleState) -> FileHandle {
let fh = FileHandle(self.pool.next());
self.state.insert(fh, state);
fh
}
pub fn close(&mut self, fh: FileHandle) -> Option<HandleState> {
self.pool.recycle(fh.0);
self.state.remove(&fh)
}
pub fn state(&self, fh: FileHandle) -> Option<&HandleState> {
self.state.get(&fh)
}
pub fn state_mut(&mut self, fh: FileHandle) -> Option<&mut HandleState> {
self.state.get_mut(&fh)
}
}