diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-01-05 06:20:54 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-01-05 06:20:54 -0600 |
| commit | b424e909fb65eb5c77a4ba4082492b11278103d4 (patch) | |
| tree | 69df0298f0401d53cd3899c1ea085dd4b02555d1 | |
| parent | 75cced9d4c101ec2f9f04ed95621ff3a3f750eae (diff) | |
Refactor impls of Request as individual traits
Diffstat (limited to '')
| -rw-r--r-- | src/ops/dir.rs | 49 | ||||
| -rw-r--r-- | src/ops/entry.rs | 40 | ||||
| -rw-r--r-- | src/ops/open.rs | 33 | ||||
| -rw-r--r-- | src/ops/rw.rs | 44 | ||||
| -rw-r--r-- | src/ops/traits.rs | 80 | ||||
| -rw-r--r-- | src/ops/xattr.rs | 40 |
6 files changed, 195 insertions, 91 deletions
diff --git a/src/ops/dir.rs b/src/ops/dir.rs index e1998cd..5bb64d2 100644 --- a/src/ops/dir.rs +++ b/src/ops/dir.rs @@ -13,7 +13,10 @@ use crate::{ use super::{ c_to_os, make_entry, - traits::{ReplyBuffered, ReplyKnown, ReplyNotFound}, + traits::{ + ReplyBuffered, ReplyKnown, ReplyNotFound, RequestHandle, RequestName, RequestOffset, + RequestSize, + }, FromRequest, }; @@ -65,10 +68,9 @@ impl<'o, B> Operation<'o> for BufferedReaddir<B> { type ReplyTail = ReaddirState<B>; } -impl<'o> Request<'o, Lookup> { - /// Returns the name of the entry being looked up in this directory. - pub fn name(&self) -> &OsStr { - c_to_os(self.body) +impl<'o> RequestName<'o> for Lookup { + fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr { + c_to_os(request.body) } } @@ -89,27 +91,21 @@ impl<'o> ReplyFound<'o> for Lookup { } } -impl<'o> Request<'o, Readdir> { - pub fn handle(&self) -> u64 { - self.read_in().fh - } - - /// Returns the base offset in the directory stream to read from. - pub fn offset(&self) -> u64 { - self.read_in().offset +impl<'o> RequestHandle<'o> for Readdir { + fn handle(request: &Request<'o, Self>) -> u64 { + readdir_read_in(request).fh } +} - pub fn size(&self) -> u32 { - self.read_in().size +impl<'o> RequestOffset<'o> for Readdir { + fn offset(request: &Request<'o, Self>) -> u64 { + readdir_read_in(request).offset } +} - fn read_in(&self) -> &proto::ReadIn { - use proto::OpcodeSelect::*; - - match &self.body { - Match(readdir_plus) => &readdir_plus.read_in, - Alt(readdir) => &readdir.read_in, - } +impl<'o> RequestSize<'o> for Readdir { + fn size(request: &Request<'o, Self>) -> u32 { + readdir_read_in(request).size } } @@ -239,3 +235,12 @@ fn dirent_pad_bytes(entry_len: usize) -> usize { const ALIGN_MASK: usize = (1 << proto::DIRENT_ALIGNMENT_BITS) - 1; ((entry_len + ALIGN_MASK) & !ALIGN_MASK) - entry_len } + +fn readdir_read_in<'a>(request: &'a Request<'_, Readdir>) -> &'a proto::ReadIn { + use proto::OpcodeSelect::*; + + match &request.body { + Match(readdir_plus) => &readdir_plus.read_in, + Alt(readdir) => &readdir.read_in, + } +} diff --git a/src/ops/entry.rs b/src/ops/entry.rs index 1bcf71f..139a506 100644 --- a/src/ops/entry.rs +++ b/src/ops/entry.rs @@ -1,13 +1,22 @@ -use super::traits::ReplyOk; +use super::traits::{ReplyOk, RequestHandle}; use crate::{io::Stat, private_trait::Sealed, proto, Done, Ino, Operation, Reply, Request}; pub enum Forget {} pub enum Getattr {} +pub trait RequestForget<'o>: Operation<'o> { + fn forget_list<'a>(request: &'a Request<'o, Self>) -> ForgetList<'a>; +} + pub trait ReplyStat<'o>: Operation<'o> { fn stat(reply: Reply<'o, Self>, inode: &impl Stat) -> Done<'o>; } +pub enum ForgetList<'a> { + Single(Option<(Ino, u64)>), + Batch(std::slice::Iter<'a, proto::ForgetOne>), +} + impl Sealed for Forget {} impl Sealed for Getattr {} @@ -26,22 +35,17 @@ impl<'o> Operation<'o> for Getattr { type ReplyTail = (); } -impl<'o> Request<'o, Forget> { - pub fn forget_list(&self) -> impl '_ + Iterator<Item = (Ino, u64)> { - use proto::OpcodeSelect::*; - - enum List<'a> { - Single(Option<(Ino, u64)>), - Batch(std::slice::Iter<'a, proto::ForgetOne>), - } +impl<'o> RequestForget<'o> for Forget { + fn forget_list<'a>(request: &'a Request<'o, Self>) -> ForgetList<'a> { + use {proto::OpcodeSelect::*, ForgetList::*}; - impl Iterator for List<'_> { + impl Iterator for ForgetList<'_> { type Item = (Ino, u64); fn next(&mut self) -> Option<Self::Item> { match self { - List::Single(single) => single.take(), - List::Batch(batch) => { + Single(single) => single.take(), + Batch(batch) => { let forget = batch.next()?; Some((Ino(forget.ino), forget.nlookup)) } @@ -49,9 +53,9 @@ impl<'o> Request<'o, Forget> { } } - match self.body { - Match((_, slice)) => List::Batch(slice.iter()), - Alt(single) => List::Single(Some((self.ino(), single.nlookup))), + match request.body { + Match((_, slice)) => Batch(slice.iter()), + Alt(single) => Single(Some((request.ino(), single.nlookup))), } } } @@ -63,9 +67,9 @@ impl<'o> ReplyOk<'o> for Forget { } } -impl<'o> Request<'o, Getattr> { - pub fn handle(&self) -> u64 { - self.body.fh +impl<'o> RequestHandle<'o> for Getattr { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fh } } diff --git a/src/ops/open.rs b/src/ops/open.rs index ab9eea7..30dc6da 100644 --- a/src/ops/open.rs +++ b/src/ops/open.rs @@ -4,7 +4,10 @@ use crate::{ proto, Done, Errno, Operation, Reply, Request, }; -use super::{traits::ReplyOk, FromRequest}; +use super::{ + traits::{ReplyOk, RequestFlags, RequestHandle}, + FromRequest, +}; pub enum Open {} pub enum Release {} @@ -65,9 +68,11 @@ impl<'o> Operation<'o> for Access { type ReplyTail = (); } -impl<'o> Request<'o, Open> { - pub fn flags(&self) -> OpenFlags { - OpenFlags::from_bits_truncate(self.body.flags.try_into().unwrap_or_default()) +impl<'o> RequestFlags<'o> for Open { + type Flags = OpenFlags; + + fn flags(request: &Request<'o, Self>) -> Self::Flags { + OpenFlags::from_bits_truncate(request.body.flags as _) } } @@ -80,9 +85,9 @@ impl<'o> ReplyOk<'o> for Open { impl<'o> ReplyOpen<'o> for Open {} impl<'o> ReplyPermissionDenied<'o> for Open {} -impl<'o> Request<'o, Release> { - pub fn handle(&self) -> u64 { - self.body.fh +impl<'o> RequestHandle<'o> for Release { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fh } } @@ -97,17 +102,19 @@ impl<'o> ReplyOk<'o> for Opendir { impl<'o> ReplyPermissionDenied<'o> for Opendir {} impl<'o> ReplyOpen<'o> for Opendir {} -impl<'o> Request<'o, Releasedir> { - pub fn handle(&self) -> u64 { - self.body.release_in.fh +impl<'o> RequestHandle<'o> for Releasedir { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.release_in.fh } } impl<'o> ReplyOk<'o> for Releasedir {} -impl<'o> Request<'o, Access> { - pub fn mask(&self) -> AccessFlags { - AccessFlags::from_bits_truncate(self.body.mask as i32) +impl<'o> RequestFlags<'o> for Access { + type Flags = AccessFlags; + + fn flags(request: &Request<'o, Self>) -> Self::Flags { + AccessFlags::from_bits_truncate(request.body.mask as i32) } } diff --git a/src/ops/rw.rs b/src/ops/rw.rs index 8206c7c..d3f8afd 100644 --- a/src/ops/rw.rs +++ b/src/ops/rw.rs @@ -1,5 +1,5 @@ use super::{ - traits::{ReplyGather, ReplyOk}, + traits::{ReplyGather, ReplyOk, RequestData, RequestHandle, RequestOffset, RequestSize}, FromRequest, }; @@ -45,33 +45,41 @@ impl<'o> Operation<'o> for Flush { impl<'o> ReplyGather<'o> for Readlink {} -impl<'o> Request<'o, Read> { - pub fn handle(&self) -> u64 { - self.body.fh +impl<'o> RequestHandle<'o> for Read { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fh } +} - pub fn offset(&self) -> u64 { - self.body.offset +impl<'o> RequestOffset<'o> for Read { + fn offset(request: &Request<'o, Self>) -> u64 { + request.body.offset } +} - pub fn size(&self) -> u32 { - self.body.size +impl<'o> RequestSize<'o> for Read { + fn size(request: &Request<'o, Self>) -> u32 { + request.body.size } } impl<'o> ReplyGather<'o> for Read {} -impl<'o> Request<'o, Write> { - pub fn handle(&self) -> u64 { - self.body.0.fh +impl<'o> RequestHandle<'o> for Write { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.0.fh } +} - pub fn offset(&self) -> u64 { - self.body.0.offset +impl<'o> RequestOffset<'o> for Write { + fn offset(request: &Request<'o, Self>) -> u64 { + request.body.0.offset } +} - pub fn data(&self) -> &[u8] { - self.body.1 +impl<'o> RequestData<'o> for Write { + fn data<'a>(request: &'a Request<'o, Self>) -> &'a [u8] { + request.body.1 } } @@ -85,9 +93,9 @@ impl<'o> ReplyAll<'o> for Write { } } -impl<'o> Request<'o, Flush> { - pub fn handle(&self) -> u64 { - self.body.fh +impl<'o> RequestHandle<'o> for Flush { + fn handle(request: &Request<'o, Self>) -> u64 { + request.body.fh } } diff --git a/src/ops/traits.rs b/src/ops/traits.rs index 8bb59e4..70e529a 100644 --- a/src/ops/traits.rs +++ b/src/ops/traits.rs @@ -1,11 +1,11 @@ use crate::{ io::{Entry, FsInfo, Interruptible, Known, Stat}, - Done, Operation, Reply, Ttl, + Done, Ino, Operation, Reply, Request, Ttl, }; pub use super::{ dir::{ReplyEntries, ReplyFound}, - entry::ReplyStat, + entry::{ReplyStat, RequestForget}, global::ReplyFsInfo, open::{ReplyOpen, ReplyPermissionDenied}, rw::ReplyAll, @@ -16,6 +16,31 @@ use super::make_entry; use bytes::BufMut; use std::{ffi::OsStr, os::unix::ffi::OsStrExt}; +pub trait RequestName<'o>: Operation<'o> { + fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr; +} + +pub trait RequestSize<'o>: Operation<'o> { + fn size(request: &Request<'o, Self>) -> u32; +} + +pub trait RequestOffset<'o>: Operation<'o> { + fn offset(request: &Request<'o, Self>) -> u64; +} + +pub trait RequestHandle<'o>: Operation<'o> { + fn handle(request: &Request<'o, Self>) -> u64; +} + +pub trait RequestData<'o>: Operation<'o> { + fn data<'a>(request: &'a Request<'o, Self>) -> &'a [u8]; +} + +pub trait RequestFlags<'o>: Operation<'o> { + type Flags: Copy; + fn flags(request: &Request<'o, Self>) -> Self::Flags; +} + pub trait ReplyOk<'o>: Operation<'o> { fn ok(reply: Reply<'o, Self>) -> Done<'o> { reply.empty() @@ -60,6 +85,57 @@ pub trait ReplyGather<'o>: Operation<'o> { } } +impl<'o, O: Operation<'o>> Request<'o, O> { + pub fn name(&self) -> &OsStr + where + O: RequestName<'o>, + { + O::name(self) + } + + pub fn size(&self) -> u32 + where + O: RequestSize<'o>, + { + O::size(self) + } + + pub fn offset(&self) -> u64 + where + O: RequestOffset<'o>, + { + O::offset(self) + } + + pub fn handle(&self) -> u64 + where + O: RequestHandle<'o>, + { + O::handle(self) + } + + pub fn data(&self) -> &[u8] + where + O: RequestData<'o>, + { + O::data(self) + } + + pub fn flags(&self) -> O::Flags + where + O: RequestFlags<'o>, + { + O::flags(self) + } + + pub fn forget_list(&self) -> impl '_ + Iterator<Item = (Ino, u64)> + where + O: RequestForget<'o>, + { + O::forget_list(self) + } +} + impl<'o, O: Operation<'o>> Reply<'o, O> { pub fn ok(self) -> Done<'o> where diff --git a/src/ops/xattr.rs b/src/ops/xattr.rs index 2de222b..33c7cef 100644 --- a/src/ops/xattr.rs +++ b/src/ops/xattr.rs @@ -4,7 +4,7 @@ use crate::{ use super::{ c_to_os, - traits::{ReplyGather, ReplyNotFound, ReplyOk}, + traits::{ReplyGather, ReplyNotFound, ReplyOk, RequestData, RequestName, RequestSize}, }; use std::ffi::{CStr, OsStr}; @@ -52,15 +52,17 @@ impl<'o> Operation<'o> for Removexattr { type ReplyTail = (); } -//TODO: flags -impl<'o> Request<'o, Setxattr> { - pub fn name(&self) -> &OsStr { - let (_header, name, _value) = self.body; +impl<'o> RequestName<'o> for Setxattr { + fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr { + let (_header, name, _value) = request.body; c_to_os(name) } +} - pub fn value(&self) -> &[u8] { - let (_header, _name, value) = self.body; +//TODO: flags +impl<'o> RequestData<'o> for Setxattr { + fn data<'a>(request: &'a Request<'o, Self>) -> &'a [u8] { + let (_header, _name, value) = request.body; value } } @@ -73,13 +75,15 @@ impl<'o> ReplyNotFound<'o> for Setxattr { } } -impl<'o> Request<'o, Getxattr> { - pub fn size(&self) -> u32 { - self.body.0.size +impl<'o> RequestSize<'o> for Getxattr { + fn size(request: &Request<'o, Self>) -> u32 { + request.body.0.size } +} - pub fn name(&self) -> &OsStr { - c_to_os(self.body.1) +impl<'o> RequestName<'o> for Getxattr { + fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr { + c_to_os(request.body.1) } } @@ -119,9 +123,9 @@ impl<'o> ReplyXattrRead<'o> for Getxattr { } } -impl<'o> Request<'o, Listxattr> { - pub fn size(&self) -> u32 { - self.body.getxattr_in.size +impl<'o> RequestSize<'o> for Listxattr { + fn size(request: &Request<'o, Self>) -> u32 { + request.body.getxattr_in.size } } @@ -140,9 +144,9 @@ impl<'o> ReplyXattrRead<'o> for Listxattr { } } -impl<'o> Request<'o, Removexattr> { - pub fn name(&self) -> &OsStr { - c_to_os(self.body) +impl<'o> RequestName<'o> for Removexattr { + fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr { + c_to_os(request.body) } } |
