1use camino::Utf8Path;
2use nom_derive::Parse;
3use serde::Serialize;
4
5use crate::common::FileAttributes;
6#[cfg(test)]
7use proptest::strategy::Strategy;
8
9pub mod kind;
10use kind::PacketType;
11
12pub mod init;
13use init::Init;
14pub mod version;
15use version::Version;
16pub mod open;
17use open::Open;
18pub mod close;
19use close::Close;
20pub mod read;
21use read::Read;
22pub mod write;
23use write::Write;
24pub mod lstat;
25use lstat::Lstat;
26pub mod fstat;
27use fstat::Fstat;
28pub mod setstat;
29use setstat::SetStat;
30pub mod fsetstat;
31use fsetstat::FSetStat;
32pub mod opendir;
33use opendir::OpenDir;
34pub mod readdir;
35use readdir::ReadDir;
36pub mod remove;
37use remove::Remove;
38pub mod mkdir;
39use mkdir::MkDir;
40pub mod rmdir;
41use rmdir::RmDir;
42pub mod realpath;
43use realpath::RealPath;
44pub mod stat;
45use stat::Stat;
46pub mod rename;
47use rename::Rename;
48pub mod readlink;
49use readlink::ReadLink;
50pub mod symlink;
51use symlink::Symlink;
52pub mod status;
53use status::Status;
54use status::StatusType;
55pub mod handle;
56use handle::Handle;
57pub mod data;
58use data::Data;
59pub mod name;
60use name::Name;
61pub mod attrs;
62use attrs::Attrs;
63pub mod extended;
64use extended::Request as ExtendedRequest;
65use extended::Response as ExtendedResponse;
66
67#[derive(Debug, Nom, Serialize)]
68#[nom(BigEndian)]
69pub struct PacketRaw<'a> {
70 pub length: u32,
71 pub kind: PacketType,
72 #[nom(Take="i.len()")]
73 pub raw_payload: &'a [u8]
74}
75
76#[derive(Clone, Debug, Eq, PartialEq, Nom, Serialize)]
77#[nom(BigEndian)]
78pub struct PacketHeader {
79 pub length: u32,
80 pub kind: PacketType
81}
82
83#[derive(Debug, Eq, PartialEq, Nom, Serialize)]
84#[nom(BigEndian)]
85pub struct Packet {
86 pub header: PacketHeader,
87 #[nom(Parse="{ |i| Payload::parse(i, header.kind) }")]
88 pub payload: Payload
89}
90
91#[cfg(test)]
92impl proptest::arbitrary::Arbitrary for Packet {
93 type Parameters = ();
94 type Strategy = proptest::strategy::BoxedStrategy<Self>;
95 fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
96 Payload::arbitrary_with(()).prop_map(|payload| payload.into_packet()).boxed()
97 }
98}
99
100pub trait PayloadTrait : Serialize + Into<Payload> {
101 const Type: PacketType;
102 fn binsize(&self) -> u32;
103
104 fn header(&self) -> PacketHeader {
105 PacketHeader{
106 length: 1 + self.binsize(),
107 kind: Self::Type
108 }
109 }
110
111 fn into_packet(self) -> Packet {
112 Packet{
113 header: self.header(),
114 payload: self.into()
115 }
116 }
117}
118
119#[derive(Debug, Eq, PartialEq, Nom, Serialize)]
120#[nom(Selector = "PacketType")]
121#[serde(untagged)]
122#[cfg_attr(test, derive(test_strategy::Arbitrary))]
123pub enum Payload {
124 #[nom(Selector = "PacketType::Init")]
125 Init(Init),
126 #[nom(Selector = "PacketType::Version")]
127 Version(Version),
128 #[nom(Selector = "PacketType::Open")]
129 Open(Open),
130 #[nom(Selector = "PacketType::Close")]
131 Close(Close),
132 #[nom(Selector = "PacketType::Read")]
133 Read(Read),
134 #[nom(Selector = "PacketType::Write")]
135 Write(Write),
136 #[nom(Selector = "PacketType::Lstat")]
137 Lstat(Lstat),
138 #[nom(Selector = "PacketType::Fstat")]
139 Fstat(Fstat),
140 #[nom(Selector = "PacketType::SetStat")]
141 SetStat(SetStat),
142 #[nom(Selector = "PacketType::FSetStat")]
143 FSetStat(FSetStat),
144 #[nom(Selector = "PacketType::OpenDir")]
145 OpenDir(OpenDir),
146 #[nom(Selector = "PacketType::ReadDir")]
147 ReadDir(ReadDir),
148 #[nom(Selector = "PacketType::Remove")]
149 Remove(Remove),
150 #[nom(Selector = "PacketType::MkDir")]
151 MkDir(MkDir),
152 #[nom(Selector = "PacketType::RmDir")]
153 RmDir(RmDir),
154 #[nom(Selector = "PacketType::RealPath")]
155 RealPath(RealPath),
156 #[nom(Selector = "PacketType::Stat")]
157 Stat(Stat),
158 #[nom(Selector = "PacketType::Rename")]
159 Rename(Rename),
160 #[nom(Selector = "PacketType::ReadLink")]
161 ReadLink(ReadLink),
162 #[nom(Selector = "PacketType::Symlink")]
163 Symlink(Symlink),
164 #[nom(Selector = "PacketType::Status")]
165 Status(Status),
166 #[nom(Selector = "PacketType::Handle")]
167 Handle(Handle),
168 #[nom(Selector = "PacketType::Data")]
169 Data(Data),
170 #[nom(Selector = "PacketType::Name")]
171 Name(Name),
172 #[nom(Selector = "PacketType::Attrs")]
173 Attrs(Attrs),
174 #[nom(Selector = "PacketType::Extended")]
175 Extended(ExtendedRequest),
176 #[nom(Selector = "PacketType::ExtendedReply")]
177 ExtendedReply(ExtendedResponse)
178}
179
180impl Payload {
181 pub fn init(version: u32, extension_data: Vec<u8>) -> Self {
182 Self::Init(Init{
183 version,
184 extension_data
185 })
186 }
187
188 pub fn version(version: u32, extension_data: Vec<u8>) -> Self {
189 Self::Version(Version{
190 version,
191 extension_data
192 })
193 }
194
195 pub fn real_path(id: u32, path: impl AsRef<Utf8Path>) -> Self {
196 Self::RealPath(RealPath{
197 id,
198 path: path.as_ref().to_path_buf()
199 })
200 }
201
202 pub fn status(id: u32, status: StatusType, message: impl AsRef<str>) -> Self {
203 Self::Status(Status{
204 id,
205 status,
206 message: message.as_ref().to_string(),
207 language: "en-US".to_string()
208 })
209 }
210
211 pub fn handle(id: u32) -> Handle {
212 Handle{
213 id,
214 handle: uuid::Uuid::new_v4()
215 }
216 }
217
218 pub fn name(id: u32) -> Name {
219 Name{
220 id,
221 files: Vec::with_capacity(1)
222 }
223 }
224
225 pub fn attrs(id: u32) -> Attrs {
226 Attrs{
227 id,
228 attrs: FileAttributes::new()
229 }
230 }
231
232 pub fn data_with_size(id: u32, size: u32) -> Data {
234 Data{
235 id,
236 data: vec![0; size as usize]
237 }
238 }
239
240 pub fn into_packet(self) -> Packet {
241 match self {
242 Self::Init(p) => p.into_packet(),
243 Self::Version(p) => p.into_packet(),
244 Self::Open(p) => p.into_packet(),
245 Self::Close(p) => p.into_packet(),
246 Self::Read(p) => p.into_packet(),
247 Self::Write(p) => p.into_packet(),
248 Self::Lstat(p) => p.into_packet(),
249 Self::Fstat(p) => p.into_packet(),
250 Self::SetStat(p) => p.into_packet(),
251 Self::FSetStat(p) => p.into_packet(),
252 Self::OpenDir(p) => p.into_packet(),
253 Self::ReadDir(p) => p.into_packet(),
254 Self::Remove(p) => p.into_packet(),
255 Self::MkDir(p) => p.into_packet(),
256 Self::RmDir(p) => p.into_packet(),
257 Self::RealPath(p) => p.into_packet(),
258 Self::Stat(p) => p.into_packet(),
259 Self::Rename(p) => p.into_packet(),
260 Self::ReadLink(p) => p.into_packet(),
261 Self::Symlink(p) => p.into_packet(),
262 Self::Status(p) => p.into_packet(),
263 Self::Handle(p) => p.into_packet(),
264 Self::Data(p) => p.into_packet(),
265 Self::Name(p) => p.into_packet(),
266 Self::Attrs(p) => p.into_packet(),
267 Self::Extended(p) => p.into_packet(),
268 Self::ExtendedReply(p) => p.into_packet()
269 }
270 }
271}
272
273