1
use serde::{Deserialize, Serialize};
2

            
3
use crate::commands::*;
4
use crate::types::*;
5

            
6
use crate::filter::Filter;
7
use crate::request_tokenizer::RequestTokenizer;
8

            
9
// TODO: SingleLineString
10

            
11
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12
pub enum Request {
13
    CommandList(Vec<Request>),
14

            
15
    // -- Query Commands -- //
16
    ClearError,
17
    CurrentSong,
18
    Idle(Option<Vec<SubSystem>>),
19
    Status,
20
    Stats,
21

            
22
    // -- Playback Commands -- //
23
    Consume(BoolOrOneshot),
24
    Crossfade(Seconds),
25
    MixRampDb(f32),
26
    MixRampDelay(Seconds),
27
    Random(bool),
28
    Repeat(bool),
29
    SetVol(VolumeValue),
30
    GetVol,
31
    Single(BoolOrOneshot),
32
    ReplayGainMode(ReplayGainModeMode),
33
    ReplayGainStatus,
34
    Volume(VolumeValue),
35

            
36
    // -- Playback Control Commands -- //
37
    Next,
38
    Pause(Option<bool>),
39
    Play(Option<SongPosition>),
40
    PlayId(Option<SongId>),
41
    Previous,
42
    Seek(SongPosition, TimeWithFractions),
43
    SeekId(SongId, TimeWithFractions),
44
    SeekCur(SeekMode, TimeWithFractions),
45
    Stop,
46

            
47
    // -- Queue Commands -- //
48
    // TODO: relative mode
49
    Add(String, Option<SongPosition>),
50
    // TODO: relative mode
51
    AddId(String, Option<SongPosition>),
52
    Clear,
53
    Delete(OneOrRange),
54
    DeleteId(SongId),
55
    // TODO: account for relative moves
56
    Move(OneOrRange, AbsouluteRelativeSongPosition),
57
    // TODO: account for relative moves
58
    MoveId(SongId, AbsouluteRelativeSongPosition),
59
    Playlist,
60
    PlaylistFind(Filter, Option<Sort>, Option<WindowRange>),
61
    PlaylistId(SongId),
62
    PlaylistInfo(Option<OneOrRange>),
63
    PlaylistSearch(Filter, Option<Sort>, Option<WindowRange>),
64
    // TODO: which type of range?
65
    PlChanges(PlaylistVersion, Option<WindowRange>),
66
    // TODO: which type of range?
67
    PlChangesPosId(PlaylistVersion, Option<WindowRange>),
68
    // TODO: which type of range?
69
    Prio(Priority, WindowRange),
70
    PrioId(Priority, Vec<SongId>),
71
    RangeId(SongId, TimeInterval),
72
    Shuffle(Option<OneOrRange>),
73
    Swap(SongPosition, SongPosition),
74
    SwapId(SongId, SongId),
75
    AddTagId(SongId, TagName, TagValue),
76
    ClearTagId(SongId, TagName),
77

            
78
    // -- Stored Playlist Commands -- //
79
    ListPlaylist(PlaylistName, Option<WindowRange>),
80
    ListPlaylistInfo(PlaylistName, Option<WindowRange>),
81
    SearchPlaylist(PlaylistName, Filter, Option<WindowRange>),
82
    ListPlaylists,
83
    Load(PlaylistName, Option<WindowRange>, Option<SongPosition>),
84
    PlaylistAdd(PlaylistName, Uri, Option<SongPosition>),
85
    PlaylistClear(PlaylistName),
86
    PlaylistDelete(PlaylistName, OneOrRange),
87
    PlaylistLength(PlaylistName),
88
    // TODO: which type of range?
89
    PlaylistMove(PlaylistName, Option<OneOrRange>, SongPosition),
90
    Rename(PlaylistName, PlaylistName),
91
    Rm(PlaylistName),
92
    Save(PlaylistName, Option<SaveMode>),
93

            
94
    // -- Music Database Commands -- //
95
    AlbumArt(Uri, Offset),
96
    Count(Filter, Option<GroupType>),
97
    GetFingerprint(Uri),
98
    Find(Filter, Option<Sort>, Option<WindowRange>),
99
    FindAdd(
100
        Filter,
101
        Option<Sort>,
102
        Option<WindowRange>,
103
        Option<SongPosition>,
104
    ),
105
    List(TagName, Option<Filter>, Vec<GroupType>, Option<WindowRange>),
106
    #[deprecated]
107
    ListAll(Option<Uri>),
108
    #[deprecated]
109
    ListAllInfo(Option<Uri>),
110
    ListFiles(Option<Uri>),
111
    LsInfo(Option<Uri>),
112
    ReadComments(Uri),
113
    ReadPicture(Uri, Offset),
114
    Search(Filter, Option<Sort>, Option<WindowRange>),
115
    SearchAdd(
116
        Filter,
117
        Option<Sort>,
118
        Option<WindowRange>,
119
        Option<SongPosition>,
120
    ),
121
    SearchAddPl(
122
        PlaylistName,
123
        Filter,
124
        Option<Sort>,
125
        Option<WindowRange>,
126
        Option<SongPosition>,
127
    ),
128
    SearchCount(Filter, Option<GroupType>),
129
    Update(Option<Uri>),
130
    Rescan(Option<Uri>),
131

            
132
    // -- Mount and Neighbor Commands -- //
133
    Mount(MountPath, Uri),
134
    Unmount(MountPath),
135
    ListMounts,
136
    ListNeighbors,
137

            
138
    // -- Sticker Commands -- //
139
    StickerGet(StickerType, Uri, String),
140
    StickerSet(StickerType, Uri, String, String),
141
    StickerInc(StickerType, Uri, String, usize),
142
    StickerDec(StickerType, Uri, String, usize),
143
    StickerDelete(StickerType, Uri, String),
144
    StickerList(StickerType, Uri),
145
    StickerFind(StickerType, Uri, String, Option<Sort>, Option<WindowRange>),
146
    StickerFindValue(
147
        StickerType,
148
        Uri,
149
        String,
150
        String,
151
        Option<Sort>,
152
        Option<WindowRange>,
153
    ),
154
    StickerNames,
155
    StickerTypes,
156
    StickerNamesTypes(Option<StickerType>),
157

            
158
    // -- Connection Commands -- //
159
    Close,
160
    Kill,
161
    Password(String),
162
    Ping,
163
    BinaryLimit(u64),
164
    TagTypes,
165
    TagTypesDisable(Vec<TagName>),
166
    TagTypesEnable(Vec<TagName>),
167
    TagTypesClear,
168
    TagTypesAll,
169
    TagTypesAvailable,
170
    TagTypesReset(Vec<TagName>),
171
    Protocol,
172
    ProtocolDisable(Vec<Feature>),
173
    ProtocolEnable(Vec<Feature>),
174
    ProtocolClear,
175
    ProtocolAll,
176
    ProtocolAvailable,
177

            
178
    // -- Partition Commands -- //
179
    Partition(PartitionName),
180
    ListPartitions,
181
    NewPartition(PartitionName),
182
    DelPartition(PartitionName),
183
    MoveOutput(String),
184

            
185
    // -- Audio Output Commands -- //
186
    DisableOutput(AudioOutputId),
187
    EnableOutput(AudioOutputId),
188
    ToggleOutput(AudioOutputId),
189
    Outputs,
190
    OutputSet(AudioOutputId, String, String),
191

            
192
    // -- Reflection Commands -- //
193
    Config,
194
    Commands,
195
    NotCommands,
196
    UrlHandlers,
197
    Decoders,
198

            
199
    // -- Client to Client Commands -- //
200
    Subscribe(ChannelName),
201
    Unsubscribe(ChannelName),
202
    Channels,
203
    ReadMessages,
204
    SendMessage(ChannelName, String),
205
}
206

            
207
macro_rules! serialize_req {
208
    ($request_enum:expr, $request_struct:ty) => {
209
        {
210
            if let Some(request) = <$request_struct as CommandRequest>::from_request_enum($request_enum) {
211
                return <$request_struct as CommandRequest>::serialize(&request);
212
            } else {
213
                panic!("Mismatched request enum and struct in serialize_request macro, this should never happen!");
214
            }
215
        }
216

            
217
    };
218
}
219

            
220
macro_rules! parse_req {
221
    ($request_struct:ty, $parts:expr) => {
222
        <$request_struct>::parse($parts).map(|req| req.into_request_enum())
223
    };
224
}
225

            
226
impl Request {
227
    pub fn serialize(self) -> String {
228
        match self {
229
            /* querying mpd status */
230
            Request::ClearError => serialize_req!(self, ClearErrorRequest),
231
            Request::CurrentSong => serialize_req!(self, CurrentSongRequest),
232
            Request::Idle(_) => serialize_req!(self, IdleRequest),
233
            Request::Status => serialize_req!(self, StatusRequest),
234
            Request::Stats => serialize_req!(self, StatsRequest),
235

            
236
            // /* playback options */
237
            Request::Consume(_) => serialize_req!(self, ConsumeRequest),
238
            Request::Crossfade(_) => serialize_req!(self, CrossfadeRequest),
239
            Request::MixRampDb(_) => serialize_req!(self, MixRampDbRequest),
240
            Request::MixRampDelay(_) => serialize_req!(self, MixRampDelayRequest),
241
            Request::Random(_) => serialize_req!(self, RandomRequest),
242
            Request::Repeat(_) => serialize_req!(self, RepeatRequest),
243
            Request::SetVol(_) => serialize_req!(self, SetVolRequest),
244
            Request::GetVol => serialize_req!(self, GetVolRequest),
245
            Request::Single(_) => serialize_req!(self, SingleRequest),
246
            Request::ReplayGainMode(_) => serialize_req!(self, ReplayGainModeRequest),
247
            Request::ReplayGainStatus => serialize_req!(self, ReplayGainStatusRequest),
248
            Request::Volume(_) => serialize_req!(self, VolumeRequest),
249

            
250
            /* playback control */
251
            Request::Next => serialize_req!(self, NextRequest),
252
            Request::Pause(_) => serialize_req!(self, PauseRequest),
253
            Request::Play(_) => serialize_req!(self, PlayRequest),
254
            Request::PlayId(_) => serialize_req!(self, PlayIdRequest),
255
            Request::Previous => serialize_req!(self, PreviousRequest),
256
            Request::Seek(_, _) => serialize_req!(self, SeekRequest),
257
            Request::SeekId(_, _) => serialize_req!(self, SeekIdRequest),
258
            Request::SeekCur(_, _) => serialize_req!(self, SeekCurRequest),
259
            Request::Stop => serialize_req!(self, StopRequest),
260

            
261
            /* queue */
262
            Request::Add(_, _) => serialize_req!(self, AddRequest),
263
            Request::AddId(_, _) => serialize_req!(self, AddIdRequest),
264
            Request::Clear => serialize_req!(self, ClearRequest),
265
            Request::Delete(_) => serialize_req!(self, DeleteRequest),
266
            Request::DeleteId(_) => serialize_req!(self, DeleteIdRequest),
267
            Request::Move(_, _) => serialize_req!(self, MoveRequest),
268
            Request::MoveId(_, _) => serialize_req!(self, MoveIdRequest),
269
            Request::Playlist => serialize_req!(self, PlaylistRequest),
270
            Request::PlaylistFind(_, _, _) => serialize_req!(self, PlaylistFindRequest),
271
            Request::PlaylistId(_) => serialize_req!(self, PlaylistIdRequest),
272
            Request::PlaylistInfo(_) => serialize_req!(self, PlaylistInfoRequest),
273
            Request::PlaylistSearch(_, _, _) => serialize_req!(self, PlaylistSearchRequest),
274
            Request::PlChanges(_, _) => serialize_req!(self, PlChangesRequest),
275
            Request::PlChangesPosId(_, _) => serialize_req!(self, PlChangesPosIdRequest),
276
            Request::Prio(_, _) => serialize_req!(self, PrioRequest),
277
            Request::PrioId(_, _) => serialize_req!(self, PrioIdRequest),
278
            Request::RangeId(_, _) => serialize_req!(self, RangeIdRequest),
279
            Request::Shuffle(_) => serialize_req!(self, ShuffleRequest),
280
            Request::Swap(_, _) => serialize_req!(self, SwapRequest),
281
            Request::SwapId(_, _) => serialize_req!(self, SwapIdRequest),
282
            Request::AddTagId(_, _, _) => serialize_req!(self, AddTagIdRequest),
283
            Request::ClearTagId(_, _) => serialize_req!(self, ClearTagIdRequest),
284

            
285
            /* stored playlists */
286
            Request::ListPlaylist(_, _) => serialize_req!(self, ListPlaylistRequest),
287
            Request::ListPlaylistInfo(_, _) => serialize_req!(self, ListPlaylistInfoRequest),
288
            Request::SearchPlaylist(_, _, _) => serialize_req!(self, SearchPlaylistRequest),
289
            Request::ListPlaylists => serialize_req!(self, ListPlaylistsRequest),
290
            Request::Load(_, _, _) => serialize_req!(self, LoadRequest),
291
            Request::PlaylistAdd(_, _, _) => serialize_req!(self, PlaylistAddRequest),
292
            Request::PlaylistClear(_) => serialize_req!(self, PlaylistClearRequest),
293
            Request::PlaylistDelete(_, _) => serialize_req!(self, PlaylistDeleteRequest),
294
            Request::PlaylistLength(_) => serialize_req!(self, PlaylistLengthRequest),
295
            Request::PlaylistMove(_, _, _) => serialize_req!(self, PlaylistMoveRequest),
296
            Request::Rename(_, _) => serialize_req!(self, RenameRequest),
297
            Request::Rm(_) => serialize_req!(self, RmRequest),
298
            Request::Save(_, _) => serialize_req!(self, SaveRequest),
299

            
300
            /* music database */
301
            Request::AlbumArt(_, _) => serialize_req!(self, AlbumArtRequest),
302
            Request::Count(_, _) => serialize_req!(self, CountRequest),
303
            Request::GetFingerprint(_) => serialize_req!(self, GetFingerprintRequest),
304
            Request::Find(_, _, _) => serialize_req!(self, FindRequest),
305
            Request::FindAdd(_, _, _, _) => serialize_req!(self, FindAddRequest),
306
            Request::List(_, _, _, _) => serialize_req!(self, ListRequest),
307
            Request::ListAll(_) => serialize_req!(self, ListAllRequest),
308
            Request::ListAllInfo(_) => serialize_req!(self, ListAllInfoRequest),
309
            Request::ListFiles(_) => serialize_req!(self, ListFilesRequest),
310
            Request::LsInfo(_) => serialize_req!(self, LsInfoRequest),
311
            Request::ReadComments(_) => serialize_req!(self, ReadCommentsRequest),
312
            Request::ReadPicture(_, _) => serialize_req!(self, ReadPictureRequest),
313
            Request::Search(_, _, _) => serialize_req!(self, SearchRequest),
314
            Request::SearchAdd(_, _, _, _) => serialize_req!(self, SearchAddRequest),
315
            Request::SearchAddPl(_, _, _, _, _) => serialize_req!(self, SearchAddPlRequest),
316
            Request::SearchCount(_, _) => serialize_req!(self, SearchCountRequest),
317
            Request::Update(_) => serialize_req!(self, UpdateRequest),
318
            Request::Rescan(_) => serialize_req!(self, RescanRequest),
319

            
320
            /* mounts and neighbors */
321
            Request::Mount(_, _) => serialize_req!(self, MountRequest),
322
            Request::Unmount(_) => serialize_req!(self, UnmountRequest),
323
            Request::ListMounts => serialize_req!(self, ListMountsRequest),
324
            Request::ListNeighbors => serialize_req!(self, ListNeighborsRequest),
325

            
326
            /* stickers */
327
            Request::StickerGet(_, _, _) => serialize_req!(self, StickerGetRequest),
328
            Request::StickerSet(_, _, _, _) => serialize_req!(self, StickerSetRequest),
329
            Request::StickerInc(_, _, _, _) => serialize_req!(self, StickerIncRequest),
330
            Request::StickerDec(_, _, _, _) => serialize_req!(self, StickerDecRequest),
331
            Request::StickerDelete(_, _, _) => serialize_req!(self, StickerDeleteRequest),
332
            Request::StickerList(_, _) => serialize_req!(self, StickerListRequest),
333
            Request::StickerFind(_, _, _, _, _) => serialize_req!(self, StickerFindRequest),
334
            Request::StickerNames => serialize_req!(self, StickerNamesRequest),
335
            Request::StickerTypes => serialize_req!(self, StickerTypesRequest),
336
            Request::StickerNamesTypes(_) => serialize_req!(self, StickerNamesTypesRequest),
337

            
338
            /* connection settings */
339
            Request::Close => serialize_req!(self, CloseRequest),
340
            Request::Kill => serialize_req!(self, KillRequest),
341
            Request::Password(_) => serialize_req!(self, PasswordRequest),
342
            Request::Ping => serialize_req!(self, PingRequest),
343
            Request::BinaryLimit(_) => serialize_req!(self, BinaryLimitRequest),
344
            Request::TagTypes => serialize_req!(self, TagTypesRequest),
345
            Request::TagTypesDisable(_) => serialize_req!(self, TagTypesDisableRequest),
346
            Request::TagTypesEnable(_) => serialize_req!(self, TagTypesEnableRequest),
347
            Request::TagTypesClear => serialize_req!(self, TagTypesClearRequest),
348
            Request::TagTypesAll => serialize_req!(self, TagTypesAllRequest),
349
            Request::TagTypesAvailable => serialize_req!(self, TagTypesAvailableRequest),
350
            Request::TagTypesReset(_) => serialize_req!(self, TagTypesResetRequest),
351
            Request::Protocol => serialize_req!(self, ProtocolRequest),
352
            Request::ProtocolDisable(_) => serialize_req!(self, ProtocolDisableRequest),
353
            Request::ProtocolEnable(_) => serialize_req!(self, ProtocolEnableRequest),
354
            Request::ProtocolClear => serialize_req!(self, ProtocolClearRequest),
355
            Request::ProtocolAll => serialize_req!(self, ProtocolAllRequest),
356
            Request::ProtocolAvailable => serialize_req!(self, ProtocolAvailableRequest),
357

            
358
            /* partition commands */
359
            Request::Partition(_) => serialize_req!(self, PartitionRequest),
360
            Request::ListPartitions => serialize_req!(self, ListPartitionsRequest),
361
            Request::NewPartition(_) => serialize_req!(self, NewPartitionRequest),
362
            Request::DelPartition(_) => serialize_req!(self, DelPartitionRequest),
363
            Request::MoveOutput(_) => serialize_req!(self, MoveOutputRequest),
364

            
365
            /* audio output devices */
366
            Request::DisableOutput(_) => serialize_req!(self, DisableOutputRequest),
367
            Request::EnableOutput(_) => serialize_req!(self, EnableOutputRequest),
368
            Request::ToggleOutput(_) => serialize_req!(self, ToggleOutputRequest),
369
            Request::Outputs => serialize_req!(self, OutputsRequest),
370
            Request::OutputSet(_, _, _) => serialize_req!(self, OutputSetRequest),
371

            
372
            /* reflection */
373
            Request::Config => serialize_req!(self, ConfigRequest),
374
            Request::Commands => serialize_req!(self, CommandsRequest),
375
            Request::NotCommands => serialize_req!(self, NotCommandsRequest),
376
            Request::UrlHandlers => serialize_req!(self, UrlHandlersRequest),
377
            Request::Decoders => serialize_req!(self, DecodersRequest),
378

            
379
            /* client to client */
380
            Request::Subscribe(_) => serialize_req!(self, SubscribeRequest),
381
            Request::Unsubscribe(_) => serialize_req!(self, UnsubscribeRequest),
382
            Request::Channels => serialize_req!(self, ChannelsRequest),
383
            Request::ReadMessages => serialize_req!(self, ReadMessagesRequest),
384
            Request::SendMessage(_, _) => serialize_req!(self, SendMessageRequest),
385

            
386
            _ => unimplemented!(),
387
        }
388
    }
389

            
390
    // TODO: upon encountering an error, there should be a function that lets you skip to the next OK,
391
    //       and continue execution. Maybe "parse_next_or_skip(&str) -> RequestParserResponse", which
392
    //       could skip stuff internally? Or do we want to report back the error with the entire command
393
    //       and let the library user decide what to do?
394
    //
395
    // TODO: should this return the remaining &str as well?
396
    pub fn parse_next(raw: &str) -> Result<Self, RequestParserError> {
397
        let (line, rest) = raw
398
            .split_once('\n')
399
            .ok_or(RequestParserError::UnexpectedEOF)?;
400
        let mut parts = RequestTokenizer::new(line);
401

            
402
        match parts.next().ok_or(RequestParserError::EmptyLine)?.trim() {
403
            "command_list_begin" => {
404
                let mut commands = Vec::new();
405
                let mut i = 1;
406
                loop {
407
                    i += 1;
408
                    let (line, _rest) = rest
409
                        .split_once('\n')
410
                        .ok_or(RequestParserError::MissingCommandListEnd)?;
411
                    match line.trim() {
412
                        "command_list_begin" => {
413
                            return Err(RequestParserError::NestedCommandList { line: i });
414
                        }
415
                        "command_list_end" => {
416
                            return Ok(Request::CommandList(commands));
417
                        }
418
                        input => {
419
                            let command = Request::parse_next(input)?;
420
                            commands.push(command);
421
                        }
422
                    }
423
                }
424
            }
425
            "command_list_end" => Err(RequestParserError::UnexpectedCommandListEnd),
426

            
427
            /* querying mpd status */
428
            ClearErrorRequest::COMMAND => parse_req!(ClearErrorRequest, parts),
429
            CurrentSongRequest::COMMAND => parse_req!(CurrentSongRequest, parts),
430
            IdleRequest::COMMAND => parse_req!(IdleRequest, parts),
431
            StatusRequest::COMMAND => parse_req!(StatusRequest, parts),
432
            StatsRequest::COMMAND => parse_req!(StatsRequest, parts),
433

            
434
            /* playback options */
435
            ConsumeRequest::COMMAND => parse_req!(ConsumeRequest, parts),
436
            CrossfadeRequest::COMMAND => parse_req!(CrossfadeRequest, parts),
437
            MixRampDbRequest::COMMAND => parse_req!(MixRampDbRequest, parts),
438
            MixRampDelayRequest::COMMAND => parse_req!(MixRampDelayRequest, parts),
439
            RandomRequest::COMMAND => parse_req!(RandomRequest, parts),
440
            RepeatRequest::COMMAND => parse_req!(RepeatRequest, parts),
441
            SetVolRequest::COMMAND => parse_req!(SetVolRequest, parts),
442
            GetVolRequest::COMMAND => parse_req!(GetVolRequest, parts),
443
            SingleRequest::COMMAND => parse_req!(SingleRequest, parts),
444
            ReplayGainModeRequest::COMMAND => parse_req!(ReplayGainModeRequest, parts),
445
            ReplayGainStatusRequest::COMMAND => parse_req!(ReplayGainStatusRequest, parts),
446
            VolumeRequest::COMMAND => parse_req!(VolumeRequest, parts),
447

            
448
            /* playback control */
449
            NextRequest::COMMAND => parse_req!(NextRequest, parts),
450
            PauseRequest::COMMAND => parse_req!(PauseRequest, parts),
451
            PlayRequest::COMMAND => parse_req!(PlayRequest, parts),
452
            PlayIdRequest::COMMAND => parse_req!(PlayIdRequest, parts),
453
            PreviousRequest::COMMAND => parse_req!(PreviousRequest, parts),
454
            SeekRequest::COMMAND => parse_req!(SeekRequest, parts),
455
            SeekIdRequest::COMMAND => parse_req!(SeekIdRequest, parts),
456
            SeekCurRequest::COMMAND => parse_req!(SeekCurRequest, parts),
457
            StopRequest::COMMAND => parse_req!(StopRequest, parts),
458

            
459
            /* queue */
460
            AddRequest::COMMAND => parse_req!(AddRequest, parts),
461
            AddIdRequest::COMMAND => parse_req!(AddIdRequest, parts),
462
            ClearRequest::COMMAND => parse_req!(ClearRequest, parts),
463
            DeleteRequest::COMMAND => parse_req!(DeleteRequest, parts),
464
            DeleteIdRequest::COMMAND => parse_req!(DeleteIdRequest, parts),
465
            MoveRequest::COMMAND => parse_req!(MoveRequest, parts),
466
            MoveIdRequest::COMMAND => parse_req!(MoveIdRequest, parts),
467
            PlaylistRequest::COMMAND => parse_req!(PlaylistRequest, parts),
468
            PlaylistFindRequest::COMMAND => parse_req!(PlaylistFindRequest, parts),
469
            PlaylistIdRequest::COMMAND => parse_req!(PlaylistIdRequest, parts),
470
            PlaylistInfoRequest::COMMAND => parse_req!(PlaylistInfoRequest, parts),
471
            PlaylistSearchRequest::COMMAND => parse_req!(PlaylistSearchRequest, parts),
472
            PlChangesRequest::COMMAND => parse_req!(PlChangesRequest, parts),
473
            PlChangesPosIdRequest::COMMAND => parse_req!(PlChangesPosIdRequest, parts),
474
            PrioRequest::COMMAND => parse_req!(PrioRequest, parts),
475
            PrioIdRequest::COMMAND => parse_req!(PrioIdRequest, parts),
476
            RangeIdRequest::COMMAND => parse_req!(RangeIdRequest, parts),
477
            ShuffleRequest::COMMAND => parse_req!(ShuffleRequest, parts),
478
            SwapRequest::COMMAND => parse_req!(SwapRequest, parts),
479
            SwapIdRequest::COMMAND => parse_req!(SwapIdRequest, parts),
480
            AddTagIdRequest::COMMAND => parse_req!(AddTagIdRequest, parts),
481
            ClearTagIdRequest::COMMAND => parse_req!(ClearTagIdRequest, parts),
482

            
483
            /* stored playlists */
484
            ListPlaylistRequest::COMMAND => parse_req!(ListPlaylistRequest, parts),
485
            ListPlaylistInfoRequest::COMMAND => parse_req!(ListPlaylistInfoRequest, parts),
486
            SearchPlaylistRequest::COMMAND => parse_req!(SearchPlaylistRequest, parts),
487
            ListPlaylistsRequest::COMMAND => parse_req!(ListPlaylistsRequest, parts),
488
            LoadRequest::COMMAND => parse_req!(LoadRequest, parts),
489
            PlaylistAddRequest::COMMAND => parse_req!(PlaylistAddRequest, parts),
490
            PlaylistClearRequest::COMMAND => parse_req!(PlaylistClearRequest, parts),
491
            PlaylistDeleteRequest::COMMAND => parse_req!(PlaylistDeleteRequest, parts),
492
            PlaylistLengthRequest::COMMAND => parse_req!(PlaylistLengthRequest, parts),
493
            PlaylistMoveRequest::COMMAND => parse_req!(PlaylistMoveRequest, parts),
494
            RenameRequest::COMMAND => parse_req!(RenameRequest, parts),
495
            RmRequest::COMMAND => parse_req!(RmRequest, parts),
496
            SaveRequest::COMMAND => parse_req!(SaveRequest, parts),
497

            
498
            /* music database */
499
            AlbumArtRequest::COMMAND => parse_req!(AlbumArtRequest, parts),
500
            CountRequest::COMMAND => parse_req!(CountRequest, parts),
501
            GetFingerprintRequest::COMMAND => parse_req!(GetFingerprintRequest, parts),
502
            FindRequest::COMMAND => parse_req!(FindRequest, parts),
503
            FindAddRequest::COMMAND => parse_req!(FindAddRequest, parts),
504
            ListRequest::COMMAND => parse_req!(ListRequest, parts),
505
            ListAllRequest::COMMAND => parse_req!(ListAllRequest, parts),
506
            ListAllInfoRequest::COMMAND => parse_req!(ListAllInfoRequest, parts),
507
            ListFilesRequest::COMMAND => parse_req!(ListFilesRequest, parts),
508
            LsInfoRequest::COMMAND => parse_req!(LsInfoRequest, parts),
509
            ReadCommentsRequest::COMMAND => parse_req!(ReadCommentsRequest, parts),
510
            ReadPictureRequest::COMMAND => parse_req!(ReadPictureRequest, parts),
511
            SearchRequest::COMMAND => parse_req!(SearchRequest, parts),
512
            SearchAddRequest::COMMAND => parse_req!(SearchAddRequest, parts),
513
            SearchAddPlRequest::COMMAND => parse_req!(SearchAddPlRequest, parts),
514
            SearchCountRequest::COMMAND => parse_req!(SearchCountRequest, parts),
515
            UpdateRequest::COMMAND => parse_req!(UpdateRequest, parts),
516
            RescanRequest::COMMAND => parse_req!(RescanRequest, parts),
517

            
518
            /* mounts and neighbors */
519
            MountRequest::COMMAND => parse_req!(MountRequest, parts),
520
            UnmountRequest::COMMAND => parse_req!(UnmountRequest, parts),
521
            ListMountsRequest::COMMAND => parse_req!(ListMountsRequest, parts),
522
            ListNeighborsRequest::COMMAND => parse_req!(ListNeighborsRequest, parts),
523

            
524
            /* stickers */
525
            StickerGetRequest::COMMAND => parse_req!(StickerGetRequest, parts),
526
            StickerSetRequest::COMMAND => parse_req!(StickerSetRequest, parts),
527
            StickerIncRequest::COMMAND => parse_req!(StickerIncRequest, parts),
528
            StickerDecRequest::COMMAND => parse_req!(StickerDecRequest, parts),
529
            StickerDeleteRequest::COMMAND => parse_req!(StickerDeleteRequest, parts),
530
            StickerListRequest::COMMAND => parse_req!(StickerListRequest, parts),
531
            StickerFindRequest::COMMAND => parse_req!(StickerFindRequest, parts),
532
            StickerNamesRequest::COMMAND => parse_req!(StickerNamesRequest, parts),
533
            StickerTypesRequest::COMMAND => parse_req!(StickerTypesRequest, parts),
534
            StickerNamesTypesRequest::COMMAND => parse_req!(StickerNamesTypesRequest, parts),
535

            
536
            /* connection settings */
537
            CloseRequest::COMMAND => parse_req!(CloseRequest, parts),
538
            KillRequest::COMMAND => parse_req!(KillRequest, parts),
539
            PasswordRequest::COMMAND => parse_req!(PasswordRequest, parts),
540
            PingRequest::COMMAND => parse_req!(PingRequest, parts),
541
            BinaryLimitRequest::COMMAND => parse_req!(BinaryLimitRequest, parts),
542
            TagTypesRequest::COMMAND => parse_req!(TagTypesRequest, parts),
543
            TagTypesDisableRequest::COMMAND => parse_req!(TagTypesDisableRequest, parts),
544
            TagTypesEnableRequest::COMMAND => parse_req!(TagTypesEnableRequest, parts),
545
            TagTypesClearRequest::COMMAND => parse_req!(TagTypesClearRequest, parts),
546
            TagTypesAllRequest::COMMAND => parse_req!(TagTypesAllRequest, parts),
547
            TagTypesAvailableRequest::COMMAND => parse_req!(TagTypesAvailableRequest, parts),
548
            TagTypesResetRequest::COMMAND => parse_req!(TagTypesResetRequest, parts),
549
            ProtocolRequest::COMMAND => parse_req!(ProtocolRequest, parts),
550
            ProtocolDisableRequest::COMMAND => parse_req!(ProtocolDisableRequest, parts),
551
            ProtocolEnableRequest::COMMAND => parse_req!(ProtocolEnableRequest, parts),
552
            ProtocolClearRequest::COMMAND => parse_req!(ProtocolClearRequest, parts),
553
            ProtocolAllRequest::COMMAND => parse_req!(ProtocolAllRequest, parts),
554
            ProtocolAvailableRequest::COMMAND => parse_req!(ProtocolAvailableRequest, parts),
555

            
556
            /* partition commands */
557
            PartitionRequest::COMMAND => parse_req!(PartitionRequest, parts),
558
            ListPartitionsRequest::COMMAND => parse_req!(ListPartitionsRequest, parts),
559
            NewPartitionRequest::COMMAND => parse_req!(NewPartitionRequest, parts),
560
            DelPartitionRequest::COMMAND => parse_req!(DelPartitionRequest, parts),
561
            MoveOutputRequest::COMMAND => parse_req!(MoveOutputRequest, parts),
562

            
563
            /* audio output devices */
564
            DisableOutputRequest::COMMAND => parse_req!(DisableOutputRequest, parts),
565
            EnableOutputRequest::COMMAND => parse_req!(EnableOutputRequest, parts),
566
            ToggleOutputRequest::COMMAND => parse_req!(ToggleOutputRequest, parts),
567
            OutputsRequest::COMMAND => parse_req!(OutputsRequest, parts),
568
            OutputSetRequest::COMMAND => parse_req!(OutputSetRequest, parts),
569

            
570
            /* reflection */
571
            ConfigRequest::COMMAND => parse_req!(ConfigRequest, parts),
572
            CommandsRequest::COMMAND => parse_req!(CommandsRequest, parts),
573
            NotCommandsRequest::COMMAND => parse_req!(NotCommandsRequest, parts),
574
            UrlHandlersRequest::COMMAND => parse_req!(UrlHandlersRequest, parts),
575
            DecodersRequest::COMMAND => parse_req!(DecodersRequest, parts),
576

            
577
            /* client to client */
578
            SubscribeRequest::COMMAND => parse_req!(SubscribeRequest, parts),
579
            UnsubscribeRequest::COMMAND => parse_req!(UnsubscribeRequest, parts),
580
            ChannelsRequest::COMMAND => parse_req!(ChannelsRequest, parts),
581
            ReadMessagesRequest::COMMAND => parse_req!(ReadMessagesRequest, parts),
582
            SendMessageRequest::COMMAND => parse_req!(SendMessageRequest, parts),
583

            
584
            _ => unimplemented!(),
585
        }
586
    }
587
}