summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlejandro Soto <alejandro@34project.org>2022-01-05 06:20:54 -0600
committerAlejandro Soto <alejandro@34project.org>2022-01-05 06:20:54 -0600
commitb424e909fb65eb5c77a4ba4082492b11278103d4 (patch)
tree69df0298f0401d53cd3899c1ea085dd4b02555d1 /src
parent75cced9d4c101ec2f9f04ed95621ff3a3f750eae (diff)
Refactor impls of Request as individual traits
Diffstat (limited to '')
-rw-r--r--src/ops/dir.rs49
-rw-r--r--src/ops/entry.rs40
-rw-r--r--src/ops/open.rs33
-rw-r--r--src/ops/rw.rs44
-rw-r--r--src/ops/traits.rs80
-rw-r--r--src/ops/xattr.rs40
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)
}
}