1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
//! Internal command representations.
//!
//! These are constructed by `ImapConnection` methods and serialized by the encoder.
//! Not part of the public API.
//!
//! Client commands are defined in RFC 3501 Section 6 / RFC 9051 Section 6.
use super::flag::Flag;
use super::mailbox::MailboxAttribute;
use super::validated::{MailboxName, SequenceSet};
/// An IMAP command to be encoded and sent to the server.
#[derive(Debug, Clone)]
pub(crate) enum Command {
// --- Authentication (RFC 3501 Section 6.2 / RFC 9051 Section 6.2) ---
/// LOGIN command (RFC 3501 Section 6.2.3).
Login { user: String, pass: String },
/// AUTHENTICATE command (RFC 3501 Section 6.2.2, RFC 4959 for SASL-IR).
Authenticate {
mechanism: String,
initial_response: Option<String>,
},
/// STARTTLS command (RFC 3501 Section 6.2.1).
StartTls,
/// LOGOUT command (RFC 3501 Section 6.1.3).
Logout,
/// UNAUTHENTICATE command (RFC 8437 Section 2).
Unauthenticate,
/// ENABLE command (RFC 5161 Section 3).
///
/// Requests the server to enable one or more IMAP extensions.
/// Each element is a capability atom (e.g., `"CONDSTORE"`, `"QRESYNC"`).
/// The server responds with an untagged `ENABLED` listing the
/// extensions it actually activated.
Enable { capabilities: Vec<String> },
// --- Mailbox management (RFC 3501 Section 6.3 / RFC 9051 Section 6.3) ---
/// LIST command (RFC 3501 Section 6.3.8, RFC 5258 for LIST-EXTENDED).
List { reference: String, pattern: String },
/// LIST with selection and/or return options (RFC 5258 Section 3 / RFC 9051 Section 6.3.9).
///
/// RFC 5258 Section 3 extends LIST to allow:
/// `LIST [select-opts] reference mailbox-pattern / pattern-list [return-opts]`
/// where selection options appear before the reference name, multiple
/// mailbox patterns are wrapped in `(<pattern1> <pattern2> ...)`, and
/// return options are encoded as `RETURN (<opt1> <opt2> ...)`.
///
/// `selection_options` and `return_options` are raw option tokens or
/// option phrases (for example `STATUS (MESSAGES UNSEEN)`), already
/// validated by the connection layer.
ListExtended {
selection_options: Vec<String>,
reference: String,
patterns: Vec<String>,
return_options: Vec<String>,
},
/// LIST with STATUS return option (RFC 5819 Section 2).
///
/// Requests both LIST and STATUS data in a single command.
/// The server interleaves LIST and STATUS untagged responses.
ListStatus {
reference: String,
pattern: String,
status_items: String,
},
/// SELECT command (RFC 3501 Section 6.3.1, RFC 7162 Section 3.1.1/3.2.5.2).
Select {
mailbox: MailboxName,
/// Optional CONDSTORE parameter (RFC 7162 Section 3.1.1).
condstore: bool,
/// Optional QRESYNC parameters (RFC 7162 Section 3.2.5.2).
qresync: Option<super::QresyncParams>,
},
/// EXAMINE command (RFC 3501 Section 6.3.2, RFC 7162 Section 3.1.1/3.2.5.2).
Examine {
mailbox: MailboxName,
/// Optional CONDSTORE parameter (RFC 7162 Section 3.1.1).
condstore: bool,
/// Optional QRESYNC parameters (RFC 7162 Section 3.2.5.2).
qresync: Option<super::QresyncParams>,
},
/// CREATE command (RFC 3501 Section 6.3.3).
Create { mailbox: MailboxName },
/// CREATE with USE special-use attributes (RFC 6154 Section 3).
///
/// RFC 6154 Section 3 / Section 6 ABNF:
/// `create-param =/ "USE" SP "(" [use-attr *(SP use-attr)] ")"`
/// where `use-attr = "\All" / "\Archive" / "\Drafts" / "\Flagged" /
/// "\Junk" / "\Sent" / "\Trash" / use-attr-ext`
///
/// Clients MUST NOT use the USE parameter unless the server advertises
/// the CREATE-SPECIAL-USE capability.
CreateSpecialUse {
mailbox: MailboxName,
special_use: Vec<MailboxAttribute>,
},
/// DELETE command (RFC 3501 Section 6.3.4).
Delete { mailbox: MailboxName },
/// RENAME command (RFC 3501 Section 6.3.5).
Rename {
mailbox: MailboxName,
new_name: MailboxName,
},
/// SUBSCRIBE command (RFC 3501 Section 6.3.6).
Subscribe { mailbox: MailboxName },
/// UNSUBSCRIBE command (RFC 3501 Section 6.3.7).
Unsubscribe { mailbox: MailboxName },
/// LSUB command (RFC 3501 Section 6.3.9).
Lsub { reference: String, pattern: String },
/// CLOSE command (RFC 3501 Section 6.4.2).
Close,
/// UNSELECT command (RFC 3691 Section 3).
///
/// Closes the currently selected mailbox without expunging deleted
/// messages — unlike CLOSE which implicitly expunges.
Unselect,
/// STATUS command (RFC 3501 Section 6.3.10).
Status { mailbox: MailboxName, items: String },
/// NAMESPACE command (RFC 2342).
Namespace,
/// CHECK command (RFC 3501 Section 6.4.1).
Check,
// --- Message operations — UID variants (RFC 3501 Section 6.4) ---
/// SEARCH command (RFC 3501 Section 6.4.4).
Search { criteria: String },
/// SEARCH RETURN (opts) command (RFC 4731 Section 3.2).
///
/// RFC 4731 Section 3.2 / Section 4 ABNF:
/// `search-return-opt = "MIN" / "MAX" / "ALL" / "COUNT"`
/// `"SEARCH" [SP "RETURN" SP "(" [search-return-opt *(SP search-return-opt)] ")"]
/// SP search-criteria`
SearchReturn {
criteria: String,
return_opts: Vec<String>,
},
/// SEARCH RETURN (SAVE) command (RFC 5182 Section 2).
///
/// Saves the search results server-side as `$` for use in subsequent commands.
SearchSave { criteria: String },
/// FETCH command (RFC 3501 Section 6.4.5, RFC 7162 Section 3.1.4.1 for CHANGEDSINCE).
Fetch {
sequence_set: SequenceSet,
items: String,
/// Optional CHANGEDSINCE modifier (RFC 7162 Section 3.1.4.1).
changed_since: Option<u64>,
},
/// STORE command (RFC 3501 Section 6.4.6, RFC 7162 for CONDSTORE).
Store {
sequence_set: SequenceSet,
operation: super::StoreOperation,
flags: Vec<Flag>,
unchanged_since: Option<u64>,
},
/// COPY command (RFC 3501 Section 6.4.7).
Copy {
sequence_set: SequenceSet,
mailbox: MailboxName,
},
/// MOVE command (RFC 6851 Section 3).
Move {
sequence_set: SequenceSet,
mailbox: MailboxName,
},
/// UID SEARCH command (RFC 3501 Section 6.4.4).
UidSearch { criteria: String },
/// UID SEARCH RETURN (opts) command (RFC 4731 Section 3.2).
///
/// RFC 4731 Section 3.2 / Section 4 ABNF:
/// `search-return-opt = "MIN" / "MAX" / "ALL" / "COUNT"`
/// `"UID" SP "SEARCH" [SP "RETURN" SP "(" [search-return-opt *(SP search-return-opt)] ")"]
/// SP search-criteria`
UidSearchReturn {
criteria: String,
return_opts: Vec<String>,
},
/// UID SEARCH RETURN (SAVE) command (RFC 5182 Section 2).
///
/// Saves the search results server-side as `$` for use in subsequent commands.
UidSearchSave { criteria: String },
/// UID FETCH command (RFC 3501 Section 6.4.5, RFC 7162 Section 3.1.4.1 for CHANGEDSINCE,
/// RFC 7162 Section 3.2.6 for VANISHED).
UidFetch {
sequence_set: SequenceSet,
items: String,
/// Optional CHANGEDSINCE modifier (RFC 7162 Section 3.1.4.1).
changed_since: Option<u64>,
/// VANISHED modifier for QRESYNC (RFC 7162 Section 3.2.6).
///
/// When `true`, the server returns `VANISHED` responses instead of
/// `EXPUNGE` for expunged messages. Requires `CHANGEDSINCE` to also
/// be set, and QRESYNC must have been `ENABLE`d first.
vanished: bool,
},
/// UID STORE command (RFC 3501 Section 6.4.6, RFC 7162 for CONDSTORE).
UidStore {
sequence_set: SequenceSet,
operation: super::StoreOperation,
flags: Vec<Flag>,
unchanged_since: Option<u64>,
},
/// UID MOVE command (RFC 6851).
UidMove {
sequence_set: SequenceSet,
mailbox: MailboxName,
},
/// UID COPY command (RFC 3501 Section 6.4.7).
UidCopy {
sequence_set: SequenceSet,
mailbox: MailboxName,
},
/// UID EXPUNGE command (RFC 4315 UIDPLUS).
UidExpunge { sequence_set: SequenceSet },
/// EXPUNGE command (RFC 3501 Section 6.4.3).
Expunge,
// --- IDLE (RFC 2177) ---
/// IDLE command (RFC 2177).
Idle,
// --- Misc ---
/// CAPABILITY command (RFC 3501 Section 6.1.1).
Capability,
/// NOOP command (RFC 3501 Section 6.1.2).
Noop,
/// ID command (RFC 2971 Section 3.1).
///
/// Values are `nstring` per RFC 2971 Section 3.1: `id_params_list ::= "(" #(string SPACE nstring) ")"`.
/// A `None` value encodes as `NIL` on the wire.
Id(Vec<(String, Option<String>)>),
// --- METADATA (RFC 5464) ---
/// GETMETADATA command (RFC 5464 Section 4.2).
GetMetadata {
mailbox: MailboxName,
entries: Vec<String>,
/// Maximum size of returned values in bytes (RFC 5464 Section 4.2.2).
max_size: Option<u64>,
/// Depth of entry hierarchy: `"0"`, `"1"`, or `"infinity"` (RFC 5464 Section 4.2.2).
depth: Option<String>,
},
/// SETMETADATA command (RFC 5464 Section 4.3).
///
/// Each entry is a `(name, value)` pair. `None` value deletes the entry.
/// RFC 5464 Section 5: `value = nstring / literal8` — values are raw bytes
/// to support binary data via the `literal8` syntax.
SetMetadata {
mailbox: MailboxName,
entries: Vec<(String, Option<Vec<u8>>)>,
},
// --- THREAD (RFC 5256) ---
/// THREAD command (RFC 5256 Section 3).
Thread {
algorithm: String,
charset: String,
criteria: String,
},
/// UID THREAD command (RFC 5256 Section 3).
UidThread {
algorithm: String,
charset: String,
criteria: String,
},
// --- SORT (RFC 5256) ---
/// SORT command (RFC 5256 Section 2).
Sort {
/// Sort criteria: one or more sort keys per RFC 5256 Section 2
/// `sort-criteria = "(" sort-key *(SP sort-key) ")"`.
sort_criteria: String,
charset: String,
criteria: String,
},
/// UID SORT command (RFC 5256 Section 2).
UidSort {
/// Sort criteria: one or more sort keys per RFC 5256 Section 2
/// `sort-criteria = "(" sort-key *(SP sort-key) ")"`.
sort_criteria: String,
charset: String,
criteria: String,
},
// --- NOTIFY (RFC 5465) ---
/// NOTIFY SET command (RFC 5465 Section 3).
///
/// Registers interest in events for specified mailbox filters.
/// Replaces any previous NOTIFY configuration.
NotifySet(super::notify::NotifySetParams),
/// NOTIFY NONE command (RFC 5465 Section 3).
///
/// Cancels all event subscriptions, reverting to baseline IMAP behavior.
NotifyNone,
// --- COMPRESS (RFC 4978) ---
/// COMPRESS command (RFC 4978 Section 4).
Compress,
// --- QUOTA (RFC 2087) ---
/// GETQUOTA command (RFC 2087 Section 4.2).
GetQuota { root: String },
/// GETQUOTAROOT command (RFC 2087 Section 4.3).
GetQuotaRoot { mailbox: MailboxName },
/// SETQUOTA command (RFC 2087 Section 4.1).
///
/// Sets resource limits on a quota root. Each element of `resources` is
/// a `(resource_name, limit)` pair — e.g. `("STORAGE", 51200)`.
SetQuota {
root: String,
resources: Vec<(String, u64)>,
},
// --- ACL (RFC 4314) ---
/// SETACL command (RFC 4314 Section 3.1).
SetAcl {
mailbox: MailboxName,
identifier: String,
rights: String,
},
/// DELETEACL command (RFC 4314 Section 3.2).
DeleteAcl {
mailbox: MailboxName,
identifier: String,
},
/// GETACL command (RFC 4314 Section 3.3).
GetAcl { mailbox: MailboxName },
/// LISTRIGHTS command (RFC 4314 Section 3.4).
ListRights {
mailbox: MailboxName,
identifier: String,
},
/// MYRIGHTS command (RFC 4314 Section 3.5).
MyRights { mailbox: MailboxName },
}
/// Classification-level command discriminant.
///
/// Used by [`crate::codec::classification::classify`] to route untagged
/// responses. UID variants map to their non-UID counterpart because they
/// produce identical solicited response sets. Similarly, `CreateSpecialUse`
/// maps to `Create`, `ListExtended` maps to `List`, and `Done` maps to
/// `Idle`.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub(crate) enum CommandKind {
// --- Any state (RFC 3501 §6.1) ---
/// CAPABILITY (RFC 3501 §6.1.1).
Capability,
/// NOOP (RFC 3501 §6.1.2).
Noop,
/// LOGOUT (RFC 3501 §6.1.3).
Logout,
// --- Not authenticated (RFC 3501 §6.2) ---
/// LOGIN (RFC 3501 §6.2.3).
Login,
/// AUTHENTICATE (RFC 3501 §6.2.2).
Authenticate,
/// STARTTLS (RFC 3501 §6.2.1).
StartTls,
// --- Authenticated (RFC 3501 §6.3) ---
/// ENABLE (RFC 5161 §3).
Enable,
/// SELECT (RFC 3501 §6.3.1).
Select,
/// EXAMINE (RFC 3501 §6.3.2).
Examine,
/// CREATE (RFC 3501 §6.3.3), including CREATE-SPECIAL-USE (RFC 6154 §3).
Create,
/// DELETE (RFC 3501 §6.3.4).
Delete,
/// RENAME (RFC 3501 §6.3.5).
Rename,
/// SUBSCRIBE (RFC 3501 §6.3.6).
Subscribe,
/// UNSUBSCRIBE (RFC 3501 §6.3.7).
Unsubscribe,
/// LIST (RFC 3501 §6.3.8) and LIST-EXTENDED (RFC 5258 §3).
List,
/// LIST with STATUS return option (RFC 5819 §2).
ListStatus,
/// LSUB (RFC 3501 §6.3.9).
Lsub,
/// STATUS (RFC 3501 §6.3.10).
Status,
/// NAMESPACE (RFC 2342).
Namespace,
/// APPEND / MULTIAPPEND (RFC 3501 §6.3.11 / RFC 3502).
Append,
// --- Selected (RFC 3501 §6.4) ---
/// CHECK (RFC 3501 §6.4.1).
Check,
/// CLOSE (RFC 3501 §6.4.2).
Close,
/// UNSELECT (RFC 3691 §3).
Unselect,
/// EXPUNGE / UID EXPUNGE (RFC 3501 §6.4.3 / RFC 4315).
Expunge,
/// SEARCH / UID SEARCH (RFC 3501 §6.4.4).
Search,
/// SEARCH RETURN / UID SEARCH RETURN (RFC 4731 §3.2).
SearchReturn,
/// SEARCH RETURN (SAVE) / UID SEARCH RETURN (SAVE) (RFC 5182 §2).
SearchSave,
/// FETCH / UID FETCH (RFC 3501 §6.4.5).
Fetch,
/// STORE / UID STORE (RFC 3501 §6.4.6).
Store,
/// COPY / UID COPY (RFC 3501 §6.4.7).
Copy,
/// MOVE / UID MOVE (RFC 6851 §3).
Move,
// --- IDLE (RFC 2177) ---
/// IDLE (RFC 2177). `Done` also maps here.
Idle,
// --- Extensions ---
/// ID (RFC 2971).
Id,
/// GETMETADATA (RFC 5464 §4.2).
GetMetadata,
/// SETMETADATA (RFC 5464 §4.3).
SetMetadata,
/// THREAD / UID THREAD (RFC 5256 §3).
Thread,
/// SORT / UID SORT (RFC 5256 §2).
Sort,
/// NOTIFY SET (RFC 5465 §3).
NotifySet,
/// NOTIFY NONE (RFC 5465 §3).
NotifyNone,
/// COMPRESS (RFC 4978 §4).
Compress,
/// UNAUTHENTICATE (RFC 8437 §2).
Unauthenticate,
/// GETQUOTA (RFC 2087 §4.2).
GetQuota,
/// GETQUOTAROOT (RFC 2087 §4.3).
GetQuotaRoot,
/// SETQUOTA (RFC 2087 §4.1).
SetQuota,
/// SETACL (RFC 4314 §3.1).
SetAcl,
/// DELETEACL (RFC 4314 §3.2).
DeleteAcl,
/// GETACL (RFC 4314 §3.3).
GetAcl,
/// LISTRIGHTS (RFC 4314 §3.4).
ListRights,
/// MYRIGHTS (RFC 4314 §3.5).
MyRights,
}
impl Command {
/// Return the mailbox target of this command, if applicable.
///
/// Used by the dispatcher to populate `ClassificationContext::command_target`
/// and `ConsumerContext::command_target` for response correlation.
/// Commands like SELECT, STATUS, GETMETADATA, etc. have an explicit
/// mailbox argument that the classification layer needs to match
/// solicited STATUS responses to the correct command (RFC 3501 §6.3.10).
pub(crate) fn mailbox_target(&self) -> Option<&MailboxName> {
match self {
Self::Select { mailbox, .. }
| Self::Examine { mailbox, .. }
| Self::Create { mailbox, .. }
| Self::CreateSpecialUse { mailbox, .. }
| Self::Delete { mailbox }
| Self::Rename { mailbox, .. }
| Self::Subscribe { mailbox }
| Self::Unsubscribe { mailbox }
| Self::Status { mailbox, .. }
| Self::GetMetadata { mailbox, .. }
| Self::SetMetadata { mailbox, .. }
| Self::Copy { mailbox, .. }
| Self::Move { mailbox, .. }
| Self::UidCopy { mailbox, .. }
| Self::UidMove { mailbox, .. }
| Self::GetAcl { mailbox }
| Self::SetAcl { mailbox, .. }
| Self::DeleteAcl { mailbox, .. }
| Self::ListRights { mailbox, .. }
| Self::MyRights { mailbox }
| Self::GetQuotaRoot { mailbox } => Some(mailbox),
_ => None,
}
}
/// Return the classification-level discriminant for this command.
///
/// UID variants map to their non-UID counterpart because they produce
/// identical solicited response sets.
pub(crate) fn kind(&self) -> CommandKind {
match self {
// Any state (RFC 3501 §6.1)
Self::Capability => CommandKind::Capability,
Self::Noop => CommandKind::Noop,
Self::Logout => CommandKind::Logout,
Self::Enable { .. } => CommandKind::Enable,
// Not authenticated (RFC 3501 §6.2)
Self::Login { .. } => CommandKind::Login,
Self::Authenticate { .. } => CommandKind::Authenticate,
Self::StartTls => CommandKind::StartTls,
// Authenticated (RFC 3501 §6.3)
Self::Select { .. } => CommandKind::Select,
Self::Examine { .. } => CommandKind::Examine,
Self::Create { .. } | Self::CreateSpecialUse { .. } => CommandKind::Create,
Self::Delete { .. } => CommandKind::Delete,
Self::Rename { .. } => CommandKind::Rename,
Self::Subscribe { .. } => CommandKind::Subscribe,
Self::Unsubscribe { .. } => CommandKind::Unsubscribe,
Self::List { .. } | Self::ListExtended { .. } => CommandKind::List,
Self::ListStatus { .. } => CommandKind::ListStatus,
Self::Lsub { .. } => CommandKind::Lsub,
Self::Status { .. } => CommandKind::Status,
Self::Namespace => CommandKind::Namespace,
// Selected (RFC 3501 §6.4)
Self::Check => CommandKind::Check,
Self::Close => CommandKind::Close,
Self::Unselect => CommandKind::Unselect,
Self::Expunge | Self::UidExpunge { .. } => CommandKind::Expunge,
Self::Search { .. } | Self::UidSearch { .. } => CommandKind::Search,
Self::SearchReturn { .. } | Self::UidSearchReturn { .. } => CommandKind::SearchReturn,
Self::SearchSave { .. } | Self::UidSearchSave { .. } => CommandKind::SearchSave,
Self::Fetch { .. } | Self::UidFetch { .. } => CommandKind::Fetch,
Self::Store { .. } | Self::UidStore { .. } => CommandKind::Store,
Self::Copy { .. } | Self::UidCopy { .. } => CommandKind::Copy,
Self::Move { .. } | Self::UidMove { .. } => CommandKind::Move,
// IDLE (RFC 2177)
Self::Idle => CommandKind::Idle,
// Extensions
Self::Id(_) => CommandKind::Id,
Self::GetMetadata { .. } => CommandKind::GetMetadata,
Self::SetMetadata { .. } => CommandKind::SetMetadata,
Self::Thread { .. } | Self::UidThread { .. } => CommandKind::Thread,
Self::Sort { .. } | Self::UidSort { .. } => CommandKind::Sort,
Self::NotifySet(_) => CommandKind::NotifySet,
Self::NotifyNone => CommandKind::NotifyNone,
Self::Compress => CommandKind::Compress,
Self::Unauthenticate => CommandKind::Unauthenticate,
Self::GetQuota { .. } => CommandKind::GetQuota,
Self::GetQuotaRoot { .. } => CommandKind::GetQuotaRoot,
Self::SetQuota { .. } => CommandKind::SetQuota,
Self::SetAcl { .. } => CommandKind::SetAcl,
Self::DeleteAcl { .. } => CommandKind::DeleteAcl,
Self::GetAcl { .. } => CommandKind::GetAcl,
Self::ListRights { .. } => CommandKind::ListRights,
Self::MyRights { .. } => CommandKind::MyRights,
}
}
}
#[cfg(test)]
#[path = "command_tests.rs"]
mod tests;