1use super::{
2 c_to_os,
3 traits::{ReplyKnown, ReplyOk, RequestMode, RequestName},
4};
5
6use crate::{
7 io::{Ino, Mode},
8 proto,
9 sealed::Sealed,
10 Operation, Request,
11};
12use std::ffi::{CStr, OsStr};
13
14pub enum Mknod {}
15pub enum Mkdir {}
16pub enum Unlink {}
17pub enum Rmdir {}
18pub enum Symlink {}
19pub enum Link {}
20
21pub trait RequestDevice<'o>: Operation<'o> {
22 fn device(request: &Request<'o, Self>) -> u32;
23}
24
25pub trait RequestTarget<'o>: Operation<'o> {
26 fn target<'a>(request: &'a Request<'o, Self>) -> &'a OsStr;
27}
28
29pub trait RequestLink<'o>: Operation<'o> {
30 fn source_ino(request: &Request<'o, Self>) -> Ino;
31}
32
33impl Sealed for Mknod {}
34impl Sealed for Mkdir {}
35impl Sealed for Unlink {}
36impl Sealed for Rmdir {}
37impl Sealed for Symlink {}
38impl Sealed for Link {}
39
40impl<'o> Operation<'o> for Mknod {
41 type RequestBody = (&'o proto::MknodIn, &'o CStr);
42 type ReplyState = ();
43}
44
45impl<'o> Operation<'o> for Mkdir {
46 type RequestBody = (&'o proto::MkdirIn, &'o CStr);
47 type ReplyState = ();
48}
49
50impl<'o> Operation<'o> for Unlink {
51 type RequestBody = &'o CStr;
52 type ReplyState = ();
53}
54
55impl<'o> Operation<'o> for Rmdir {
56 type RequestBody = &'o CStr;
57 type ReplyState = ();
58}
59
60impl<'o> Operation<'o> for Symlink {
61 type RequestBody = (&'o CStr, &'o CStr); type ReplyState = ();
63}
64
65impl<'o> Operation<'o> for Link {
66 type RequestBody = (&'o proto::LinkIn, &'o CStr);
67 type ReplyState = ();
68}
69
70impl<'o> RequestName<'o> for Mknod {
71 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
72 let (_header, name) = request.body;
73 c_to_os(name)
74 }
75}
76
77impl<'o> RequestMode<'o> for Mknod {
78 fn mode(request: &Request<'o, Self>) -> Mode {
79 let (header, _name) = request.body;
80 Mode::from_bits_truncate(header.mode)
81 }
82
83 fn umask(request: &Request<'o, Self>) -> Mode {
84 let (header, _name) = request.body;
85 Mode::from_bits_truncate(header.umask)
86 }
87}
88
89impl<'o> RequestDevice<'o> for Mknod {
90 fn device(request: &Request<'o, Self>) -> u32 {
91 let (header, _name) = request.body;
92 header.device
93 }
94}
95
96impl<'o> ReplyKnown<'o> for Mknod {}
97
98impl<'o> RequestName<'o> for Mkdir {
99 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
100 let (_header, name) = request.body;
101 c_to_os(name)
102 }
103}
104
105impl<'o> RequestMode<'o> for Mkdir {
106 fn mode(request: &Request<'o, Self>) -> Mode {
107 let (header, _name) = request.body;
108 Mode::from_bits_truncate(header.mode)
109 }
110
111 fn umask(request: &Request<'o, Self>) -> Mode {
112 let (header, _name) = request.body;
113 Mode::from_bits_truncate(header.umask)
114 }
115}
116
117impl<'o> ReplyKnown<'o> for Mkdir {}
118
119impl<'o> RequestName<'o> for Unlink {
120 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
121 c_to_os(request.body)
122 }
123}
124
125impl<'o> ReplyOk<'o> for Unlink {}
126
127impl<'o> RequestName<'o> for Rmdir {
128 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
129 c_to_os(request.body)
130 }
131}
132
133impl<'o> ReplyOk<'o> for Rmdir {}
134
135impl<'o> RequestName<'o> for Symlink {
136 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
137 let (name, _target) = request.body;
138 c_to_os(name)
139 }
140}
141
142impl<'o> RequestTarget<'o> for Symlink {
143 fn target<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
144 let (_name, target) = request.body;
145 c_to_os(target)
146 }
147}
148
149impl<'o> ReplyKnown<'o> for Symlink {}
150
151impl<'o> RequestName<'o> for Link {
152 fn name<'a>(request: &'a Request<'o, Self>) -> &'a OsStr {
153 let (_header, name) = request.body;
154 c_to_os(name)
155 }
156}
157
158impl<'o> RequestLink<'o> for Link {
159 fn source_ino(request: &Request<'o, Self>) -> Ino {
160 let (header, _name) = request.body;
161 Ino(header.old_ino)
162 }
163}
164
165impl<'o> ReplyKnown<'o> for Link {}