use async_trait::async_trait; use nix::errno::Errno; use std::{ num::NonZeroUsize, ops::{Deref, DerefMut}, sync::Arc, }; use crate::{Ino, TimeToLive}; use super::{ io::{Attrs, EntryType}, ops::*, Done, Op, Reply, }; #[async_trait] pub trait Fuse: Sized + Send + Sync + 'static { type Inode: Inode + ?Sized; type Farc: Deref + Clone + Send + Sync = Arc; async fn init<'o>(&self, reply: Reply<'o, Self, Init>) -> Done<'o>; async fn statfs<'o>(&self, (_, reply, _): Op<'o, Self, Statfs>) -> Done<'o> { reply.not_implemented() } fn request_buffers(&self) -> NonZeroUsize { NonZeroUsize::new(16).unwrap() } fn request_buffer_pages(&self) -> NonZeroUsize { NonZeroUsize::new(4).unwrap() } } #[async_trait] pub trait Inode: Send + Sync { type Fuse: Fuse; fn ino(self: &FarcTo) -> Ino; fn attrs(self: &FarcTo) -> (Attrs, TimeToLive); fn inode_type(self: &FarcTo) -> EntryType; fn direct_io<'o>(self: &FarcTo) -> bool { false } fn access<'o>(self: &FarcTo, (_, reply, _): Op<'o, Self::Fuse, Access>) -> Done<'o> { reply.not_implemented() } async fn lookup<'o>(self: FarcTo, (_, reply, _): Op<'o, Self::Fuse, Lookup>) -> Done<'o> { reply.not_implemented() } async fn readlink<'o>( self: FarcTo, (_, reply, _): Op<'o, Self::Fuse, Readlink>, ) -> Done<'o> { reply.not_implemented() } async fn open<'o>(self: FarcTo, (_, reply, _): Op<'o, Self::Fuse, Open>) -> Done<'o> { // Calling not_implemented() here would ignore direct_io() and similar flags reply.ok() } async fn opendir<'o>( self: FarcTo, (_, reply, _): Op<'o, Self::Fuse, Opendir>, ) -> Done<'o> { reply.not_implemented() } async fn readdir<'o>( self: FarcTo, (_, reply, _): Op<'o, Self::Fuse, Readdir>, ) -> Done<'o> { reply.not_implemented() } } #[async_trait] pub trait Tape: Send + Sync { type Fuse: Fuse; async fn seek(self: &mut Head, offset: u64) -> Result<(), Errno>; async fn rewind(self: &mut Head) -> Result<(), Errno> { self.seek(0).await } async fn read<'o>(self: &mut Head, (_, reply, _): Op<'o, Self::Fuse, Read>) -> Done<'o> { reply.not_implemented() } async fn write<'o>( self: &mut Head, (_, reply, _): Op<'o, Self::Fuse, Write>, ) -> Done<'o> { reply.not_implemented() } } pub type FarcTo = <::Fuse as Fuse>::Farc; pub struct Head { offset: u64, inode: ::Farc, tape: T, } impl Deref for Head { type Target = T; fn deref(&self) -> &Self::Target { &self.tape } } impl DerefMut for Head { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.tape } }