Add more commands
This commit is contained in:
parent
3e512092bd
commit
2ee6bbc582
@ -4,17 +4,27 @@ use crate::Request;
|
||||
|
||||
mod audio_output_devices;
|
||||
mod client_to_client;
|
||||
mod connection_settings;
|
||||
mod controlling_playback;
|
||||
mod mounts_and_neighbors;
|
||||
mod partition_commands;
|
||||
mod playback_options;
|
||||
mod querying_mpd_status;
|
||||
mod queue;
|
||||
mod reflection;
|
||||
mod stored_playlists;
|
||||
|
||||
pub use audio_output_devices::*;
|
||||
pub use client_to_client::*;
|
||||
pub use connection_settings::*;
|
||||
pub use controlling_playback::*;
|
||||
pub use mounts_and_neighbors::*;
|
||||
pub use partition_commands::*;
|
||||
pub use playback_options::*;
|
||||
pub use querying_mpd_status::*;
|
||||
pub use queue::*;
|
||||
pub use reflection::*;
|
||||
pub use stored_playlists::*;
|
||||
|
||||
pub trait Command {
|
||||
type Response;
|
||||
@ -87,10 +97,13 @@ pub enum RequestParserError {
|
||||
MissingNewline,
|
||||
}
|
||||
|
||||
// TODO: should these be renamed to fit the mpd docs?
|
||||
// "Attribute" instead of "Property"?
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum ResponseParserError<'a> {
|
||||
MissingProperty(&'a str),
|
||||
UnexpectedPropertyType(&'a str, &'a str),
|
||||
UnexpectedProperty(&'a str),
|
||||
InvalidProperty(&'a str, &'a str),
|
||||
SyntaxError(u64, &'a str),
|
||||
UnexpectedEOF,
|
||||
|
@ -8,4 +8,4 @@ pub use disableoutput::DisableOutput;
|
||||
pub use enableoutput::EnableOutput;
|
||||
pub use outputs::Outputs;
|
||||
pub use outputset::OutputSet;
|
||||
pub use toggleoutput::ToggleOutput;
|
||||
pub use toggleoutput::ToggleOutput;
|
||||
|
37
src/commands/connection_settings.rs
Normal file
37
src/commands/connection_settings.rs
Normal file
@ -0,0 +1,37 @@
|
||||
pub mod binary_limit;
|
||||
pub mod close;
|
||||
pub mod kill;
|
||||
pub mod password;
|
||||
pub mod ping;
|
||||
pub mod protocol;
|
||||
pub mod protocol_all;
|
||||
pub mod protocol_available;
|
||||
pub mod protocol_clear;
|
||||
pub mod protocol_disable;
|
||||
pub mod protocol_enable;
|
||||
pub mod tag_types;
|
||||
pub mod tag_types_all;
|
||||
pub mod tag_types_available;
|
||||
pub mod tag_types_clear;
|
||||
pub mod tag_types_disable;
|
||||
pub mod tag_types_enable;
|
||||
pub mod tag_types_reset;
|
||||
|
||||
pub use binary_limit::BinaryLimit;
|
||||
pub use close::Close;
|
||||
pub use kill::Kill;
|
||||
pub use password::Password;
|
||||
pub use ping::Ping;
|
||||
pub use protocol::Protocol;
|
||||
pub use protocol_all::ProtocolAll;
|
||||
pub use protocol_available::ProtocolAvailable;
|
||||
pub use protocol_clear::ProtocolClear;
|
||||
pub use protocol_disable::ProtocolDisable;
|
||||
pub use protocol_enable::ProtocolEnable;
|
||||
pub use tag_types::TagTypes;
|
||||
pub use tag_types_all::TagTypesAll;
|
||||
pub use tag_types_available::TagTypesAvailable;
|
||||
pub use tag_types_clear::TagTypesClear;
|
||||
pub use tag_types_disable::TagTypesDisable;
|
||||
pub use tag_types_enable::TagTypesEnable;
|
||||
pub use tag_types_reset::TagTypesReset;
|
27
src/commands/connection_settings/binary_limit.rs
Normal file
27
src/commands/connection_settings/binary_limit.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct BinaryLimit;
|
||||
|
||||
impl Command for BinaryLimit {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "binarylimit";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let limit = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let limit = limit
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, limit.to_string()))?;
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::BinaryLimit(limit), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/close.rs
Normal file
22
src/commands/connection_settings/close.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Close;
|
||||
|
||||
impl Command for Close {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "close";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Close, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/kill.rs
Normal file
22
src/commands/connection_settings/kill.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Kill;
|
||||
|
||||
impl Command for Kill {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "kill";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Kill, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
27
src/commands/connection_settings/password.rs
Normal file
27
src/commands/connection_settings/password.rs
Normal file
@ -0,0 +1,27 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Password;
|
||||
|
||||
impl Command for Password {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "password";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let password = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Password(password), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/ping.rs
Normal file
22
src/commands/connection_settings/ping.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Ping;
|
||||
|
||||
impl Command for Ping {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "ping";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Ping, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/protocol.rs
Normal file
22
src/commands/connection_settings/protocol.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct Protocol;
|
||||
|
||||
impl Command for Protocol {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Protocol, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
23
src/commands/connection_settings/protocol_all.rs
Normal file
23
src/commands/connection_settings/protocol_all.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ProtocolAll;
|
||||
|
||||
impl Command for ProtocolAll {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol all";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ProtocolAll, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/protocol_available.rs
Normal file
22
src/commands/connection_settings/protocol_available.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ProtocolAvailable;
|
||||
|
||||
impl Command for ProtocolAvailable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol available";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ProtocolAvailable, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
23
src/commands/connection_settings/protocol_clear.rs
Normal file
23
src/commands/connection_settings/protocol_clear.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ProtocolClear;
|
||||
|
||||
impl Command for ProtocolClear {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol clear";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ProtocolClear, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/connection_settings/protocol_disable.rs
Normal file
34
src/commands/connection_settings/protocol_disable.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ProtocolDisable;
|
||||
|
||||
impl Command for ProtocolDisable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol disable";
|
||||
|
||||
fn parse_request(parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
}
|
||||
|
||||
let mut protocols = Vec::new();
|
||||
for protocol in parts {
|
||||
protocols.push(protocol.to_string());
|
||||
}
|
||||
|
||||
Ok((Request::ProtocolDisable(protocols), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/connection_settings/protocol_enable.rs
Normal file
34
src/commands/connection_settings/protocol_enable.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ProtocolEnable;
|
||||
|
||||
impl Command for ProtocolEnable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "protocol enable";
|
||||
|
||||
fn parse_request(parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
}
|
||||
|
||||
let mut protocols = Vec::new();
|
||||
for protocol in parts {
|
||||
protocols.push(protocol.to_string());
|
||||
}
|
||||
|
||||
Ok((Request::ProtocolEnable(protocols), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
42
src/commands/connection_settings/tag_types.rs
Normal file
42
src/commands/connection_settings/tag_types.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use crate::commands::{
|
||||
Command, GenericResponseValue, Request, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct TagTypes;
|
||||
|
||||
pub type TagTypesResponse = Vec<String>;
|
||||
|
||||
impl Command for TagTypes {
|
||||
type Response = TagTypesResponse;
|
||||
const COMMAND: &'static str = "tagtypes";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::TagTypes, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: Vec<_> = parts.into();
|
||||
|
||||
let mut tagtypes = Vec::with_capacity(parts.len());
|
||||
for (key, value) in parts.into_iter() {
|
||||
debug_assert_eq!(key, "tagtype");
|
||||
|
||||
let tagtype = match value {
|
||||
GenericResponseValue::Text(name) => name.to_string(),
|
||||
GenericResponseValue::Binary(_) => {
|
||||
return Err(ResponseParserError::UnexpectedPropertyType(
|
||||
"tagtype", "Binary",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
tagtypes.push(tagtype);
|
||||
}
|
||||
|
||||
Ok(tagtypes)
|
||||
}
|
||||
}
|
23
src/commands/connection_settings/tag_types_all.rs
Normal file
23
src/commands/connection_settings/tag_types_all.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesAll;
|
||||
|
||||
impl Command for TagTypesAll {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes all";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::TagTypesAll, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
22
src/commands/connection_settings/tag_types_available.rs
Normal file
22
src/commands/connection_settings/tag_types_available.rs
Normal file
@ -0,0 +1,22 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesAvailable;
|
||||
|
||||
impl Command for TagTypesAvailable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes available";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::TagTypesAvailable, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
23
src/commands/connection_settings/tag_types_clear.rs
Normal file
23
src/commands/connection_settings/tag_types_clear.rs
Normal file
@ -0,0 +1,23 @@
|
||||
use crate::{
|
||||
commands::{Command, RequestParserResult, ResponseAttributes, ResponseParserError},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesClear;
|
||||
|
||||
impl Command for TagTypesClear {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes clear";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::TagTypesClear, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/connection_settings/tag_types_disable.rs
Normal file
34
src/commands/connection_settings/tag_types_disable.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesDisable;
|
||||
|
||||
impl Command for TagTypesDisable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes disable";
|
||||
|
||||
fn parse_request(parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
}
|
||||
|
||||
let mut tag_types = Vec::new();
|
||||
for tag_type in parts {
|
||||
tag_types.push(tag_type.to_string());
|
||||
}
|
||||
|
||||
Ok((Request::TagTypesDisable(tag_types), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/connection_settings/tag_types_enable.rs
Normal file
34
src/commands/connection_settings/tag_types_enable.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesEnable;
|
||||
|
||||
impl Command for TagTypesEnable {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes enable";
|
||||
|
||||
fn parse_request(parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
}
|
||||
|
||||
let mut tag_types = Vec::new();
|
||||
for tag_type in parts {
|
||||
tag_types.push(tag_type.to_string());
|
||||
}
|
||||
|
||||
Ok((Request::TagTypesEnable(tag_types), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/connection_settings/tag_types_reset.rs
Normal file
34
src/commands/connection_settings/tag_types_reset.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct TagTypesReset;
|
||||
|
||||
impl Command for TagTypesReset {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "tagtypes reset";
|
||||
|
||||
fn parse_request(parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let mut parts = parts.peekable();
|
||||
if parts.peek().is_none() {
|
||||
return Err(RequestParserError::UnexpectedEOF);
|
||||
}
|
||||
|
||||
let mut tag_types = Vec::new();
|
||||
for tag_type in parts {
|
||||
tag_types.push(tag_type.to_string());
|
||||
}
|
||||
|
||||
Ok((Request::TagTypesReset(tag_types), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
9
src/commands/mounts_and_neighbors.rs
Normal file
9
src/commands/mounts_and_neighbors.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub mod listmounts;
|
||||
pub mod listneighbors;
|
||||
pub mod mount;
|
||||
pub mod unmount;
|
||||
|
||||
pub use listmounts::ListMounts;
|
||||
pub use listneighbors::ListNeighbors;
|
||||
pub use mount::Mount;
|
||||
pub use unmount::Unmount;
|
49
src/commands/mounts_and_neighbors/listmounts.rs
Normal file
49
src/commands/mounts_and_neighbors/listmounts.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
// pub struct Unmount;
|
||||
|
||||
// impl Command for Unmount {
|
||||
// type Response = ();
|
||||
// const COMMAND: &'static str = "unmount";
|
||||
|
||||
// fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
// let path = parts
|
||||
// .next()
|
||||
// .ok_or(RequestParserError::UnexpectedEOF)?
|
||||
// .to_string();
|
||||
|
||||
// debug_assert!(parts.next().is_none());
|
||||
|
||||
// Ok((Request::Unmount(path), ""))
|
||||
// }
|
||||
|
||||
// fn parse_response(
|
||||
// parts: ResponseAttributes<'_>,
|
||||
// ) -> Result<Self::Response, ResponseParserError> {
|
||||
// debug_assert!(parts.is_empty());
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct ListMounts;
|
||||
|
||||
impl Command for ListMounts {
|
||||
type Response = Vec<(String, String)>;
|
||||
const COMMAND: &'static str = "listmounts";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ListMounts, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
24
src/commands/mounts_and_neighbors/listneighbors.rs
Normal file
24
src/commands/mounts_and_neighbors/listneighbors.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct ListNeighbors;
|
||||
|
||||
impl Command for ListNeighbors {
|
||||
type Response = Vec<(String, String)>;
|
||||
const COMMAND: &'static str = "listneighbors";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ListNeighbors, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
36
src/commands/mounts_and_neighbors/mount.rs
Normal file
36
src/commands/mounts_and_neighbors/mount.rs
Normal file
@ -0,0 +1,36 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct Mount;
|
||||
|
||||
impl Command for Mount {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "mount";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let path = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let uri = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Mount(path, uri), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
31
src/commands/mounts_and_neighbors/unmount.rs
Normal file
31
src/commands/mounts_and_neighbors/unmount.rs
Normal file
@ -0,0 +1,31 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, RequestParserError, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
Request,
|
||||
};
|
||||
|
||||
pub struct Unmount;
|
||||
|
||||
impl Command for Unmount {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "unmount";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let path = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Unmount(path), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
11
src/commands/partition_commands.rs
Normal file
11
src/commands/partition_commands.rs
Normal file
@ -0,0 +1,11 @@
|
||||
pub mod delpartition;
|
||||
pub mod listpartitions;
|
||||
pub mod moveoutput;
|
||||
pub mod newpartition;
|
||||
pub mod partition;
|
||||
|
||||
pub use delpartition::DelPartition;
|
||||
pub use listpartitions::ListPartitions;
|
||||
pub use moveoutput::MoveOutput;
|
||||
pub use newpartition::NewPartition;
|
||||
pub use partition::Partition;
|
29
src/commands/partition_commands/delpartition.rs
Normal file
29
src/commands/partition_commands/delpartition.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct DelPartition;
|
||||
|
||||
impl Command for DelPartition {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "delpartition";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let partition = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::DelPartition(partition), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
43
src/commands/partition_commands/listpartitions.rs
Normal file
43
src/commands/partition_commands/listpartitions.rs
Normal file
@ -0,0 +1,43 @@
|
||||
use crate::commands::{
|
||||
Command, GenericResponseValue, Request, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct ListPartitions;
|
||||
|
||||
pub type ListPartitionsResponse = Vec<String>;
|
||||
|
||||
impl Command for ListPartitions {
|
||||
type Response = ListPartitionsResponse;
|
||||
const COMMAND: &'static str = "listpartitions";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ListPartitions, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: Vec<_> = parts.into();
|
||||
|
||||
let mut partitions = Vec::with_capacity(parts.len());
|
||||
for (key, value) in parts.into_iter() {
|
||||
debug_assert_eq!(key, "partition");
|
||||
|
||||
let partition = match value {
|
||||
GenericResponseValue::Text(name) => name.to_string(),
|
||||
GenericResponseValue::Binary(_) => {
|
||||
return Err(ResponseParserError::UnexpectedPropertyType(
|
||||
"partition",
|
||||
"Binary",
|
||||
))
|
||||
}
|
||||
};
|
||||
|
||||
partitions.push(partition);
|
||||
}
|
||||
|
||||
Ok(partitions)
|
||||
}
|
||||
}
|
29
src/commands/partition_commands/moveoutput.rs
Normal file
29
src/commands/partition_commands/moveoutput.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct MoveOutput;
|
||||
|
||||
impl Command for MoveOutput {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "moveoutput";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let output_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::MoveOutput(output_name), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
29
src/commands/partition_commands/newpartition.rs
Normal file
29
src/commands/partition_commands/newpartition.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct NewPartition;
|
||||
|
||||
impl Command for NewPartition {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "newpartition";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let partition = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::NewPartition(partition), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
29
src/commands/partition_commands/partition.rs
Normal file
29
src/commands/partition_commands/partition.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Partition;
|
||||
|
||||
impl Command for Partition {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "partition";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let partition = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Partition(partition), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,9 +1,12 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::{commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
}, request::VolumeValue};
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
},
|
||||
request::VolumeValue,
|
||||
};
|
||||
|
||||
pub struct Volume;
|
||||
|
||||
|
11
src/commands/reflection.rs
Normal file
11
src/commands/reflection.rs
Normal file
@ -0,0 +1,11 @@
|
||||
pub mod commands;
|
||||
pub mod config;
|
||||
pub mod decoders;
|
||||
pub mod not_commands;
|
||||
pub mod url_handlers;
|
||||
|
||||
pub use commands::Commands;
|
||||
pub use config::Config;
|
||||
pub use decoders::Decoders;
|
||||
pub use not_commands::NotCommands;
|
||||
pub use url_handlers::UrlHandlers;
|
21
src/commands/reflection/commands.rs
Normal file
21
src/commands/reflection/commands.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Commands;
|
||||
|
||||
impl Command for Commands {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "commands";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Commands, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
42
src/commands/reflection/config.rs
Normal file
42
src/commands/reflection/config.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::commands::{
|
||||
get_and_parse_property, get_property, Command, Request, RequestParserResult,
|
||||
ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Config;
|
||||
|
||||
pub struct ConfigResponse {
|
||||
pub music_directory: String,
|
||||
pub playlist_directory: String,
|
||||
pub pcre: bool,
|
||||
}
|
||||
|
||||
impl Command for Config {
|
||||
type Response = ConfigResponse;
|
||||
const COMMAND: &'static str = "config";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Config, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: HashMap<_, _> = parts.into();
|
||||
|
||||
let music_directory = get_property!(parts, "music_directory", Text).to_string();
|
||||
let playlist_directory = get_property!(parts, "playlist_directory", Text).to_string();
|
||||
|
||||
// TODO: is this parsed correctly?
|
||||
let pcre = get_and_parse_property!(parts, "pcre", Text);
|
||||
|
||||
Ok(ConfigResponse {
|
||||
music_directory,
|
||||
playlist_directory,
|
||||
pcre,
|
||||
})
|
||||
}
|
||||
}
|
29
src/commands/reflection/decoders.rs
Normal file
29
src/commands/reflection/decoders.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Decoders;
|
||||
|
||||
pub struct Decoder {
|
||||
pub plugin: String,
|
||||
pub suffixes: Vec<String>,
|
||||
pub mime_types: Vec<String>,
|
||||
}
|
||||
|
||||
pub type DecodersResponse = Vec<Decoder>;
|
||||
|
||||
impl Command for Decoders {
|
||||
type Response = DecodersResponse;
|
||||
const COMMAND: &'static str = "decoders";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::Decoders, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
21
src/commands/reflection/not_commands.rs
Normal file
21
src/commands/reflection/not_commands.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct NotCommands;
|
||||
|
||||
impl Command for NotCommands {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "not_commands";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::NotCommands, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
40
src/commands/reflection/url_handlers.rs
Normal file
40
src/commands/reflection/url_handlers.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use crate::commands::{
|
||||
Command, GenericResponseValue, Request, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct UrlHandlers;
|
||||
|
||||
pub type UrlHandlersResponse = Vec<String>;
|
||||
|
||||
impl Command for UrlHandlers {
|
||||
type Response = UrlHandlersResponse;
|
||||
const COMMAND: &'static str = "urlhandlers";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::UrlHandlers, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: Vec<_> = parts.into();
|
||||
let mut url_handlers = Vec::new();
|
||||
for (key, value) in parts.into_iter() {
|
||||
if key != "handler" {
|
||||
return Err(ResponseParserError::UnexpectedProperty(key));
|
||||
}
|
||||
let value = match value {
|
||||
GenericResponseValue::Text(value) => value,
|
||||
GenericResponseValue::Binary(_) => {
|
||||
return Err(ResponseParserError::UnexpectedPropertyType(
|
||||
"handler", "Binary",
|
||||
))
|
||||
}
|
||||
};
|
||||
url_handlers.push(value.to_string());
|
||||
}
|
||||
Ok(url_handlers)
|
||||
}
|
||||
}
|
27
src/commands/stored_playlists.rs
Normal file
27
src/commands/stored_playlists.rs
Normal file
@ -0,0 +1,27 @@
|
||||
pub mod listplaylist;
|
||||
pub mod listplaylistinfo;
|
||||
pub mod listplaylists;
|
||||
pub mod load;
|
||||
pub mod playlistadd;
|
||||
pub mod playlistclear;
|
||||
pub mod playlistdelete;
|
||||
pub mod playlistlength;
|
||||
pub mod playlistmove;
|
||||
pub mod rename;
|
||||
pub mod rm;
|
||||
pub mod save;
|
||||
pub mod searchplaylist;
|
||||
|
||||
pub use listplaylist::ListPlaylist;
|
||||
pub use listplaylistinfo::ListPlaylistInfo;
|
||||
pub use listplaylists::ListPlaylists;
|
||||
pub use load::Load;
|
||||
pub use playlistadd::PlaylistAdd;
|
||||
pub use playlistclear::PlaylistClear;
|
||||
pub use playlistdelete::PlaylistDelete;
|
||||
pub use playlistlength::PlaylistLength;
|
||||
pub use playlistmove::PlaylistMove;
|
||||
pub use rename::Rename;
|
||||
pub use rm::Rm;
|
||||
pub use save::Save;
|
||||
pub use searchplaylist::SearchPlaylist;
|
53
src/commands/stored_playlists/listplaylist.rs
Normal file
53
src/commands/stored_playlists/listplaylist.rs
Normal file
@ -0,0 +1,53 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, GenericResponseValue, Request, RequestParserError, RequestParserResult,
|
||||
ResponseAttributes, ResponseParserError,
|
||||
},
|
||||
common::PlaylistName,
|
||||
};
|
||||
|
||||
pub struct ListPlaylist;
|
||||
|
||||
pub type ListPlaylistResponse = Vec<PlaylistName>;
|
||||
|
||||
impl Command for ListPlaylist {
|
||||
type Response = ListPlaylistResponse;
|
||||
const COMMAND: &'static str = "listplaylist";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = name
|
||||
.parse::<PlaylistName>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, name.to_owned()))?;
|
||||
|
||||
let range = parts
|
||||
.next()
|
||||
.map(|s| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::ListPlaylist(name.to_string(), range), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: Vec<_> = parts.into();
|
||||
parts
|
||||
.into_iter()
|
||||
.map(|(name, value)| {
|
||||
debug_assert_eq!(name, "file");
|
||||
match value {
|
||||
GenericResponseValue::Text(value) => Ok(value.to_string()),
|
||||
GenericResponseValue::Binary(_) => Err(
|
||||
ResponseParserError::UnexpectedPropertyType("file", "Binary"),
|
||||
),
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
}
|
39
src/commands/stored_playlists/listplaylistinfo.rs
Normal file
39
src/commands/stored_playlists/listplaylistinfo.rs
Normal file
@ -0,0 +1,39 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
},
|
||||
common::PlaylistName,
|
||||
};
|
||||
|
||||
pub struct ListPlaylistInfo;
|
||||
|
||||
impl Command for ListPlaylistInfo {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "listplaylistinfo";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = name
|
||||
.parse::<PlaylistName>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, name.to_owned()))?;
|
||||
|
||||
let range = parts
|
||||
.next()
|
||||
.map(|s| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::ListPlaylistInfo(name, range), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
21
src/commands/stored_playlists/listplaylists.rs
Normal file
21
src/commands/stored_playlists/listplaylists.rs
Normal file
@ -0,0 +1,21 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserResult, ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct ListPlaylists;
|
||||
|
||||
impl Command for ListPlaylists {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "listplaylists";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
debug_assert!(parts.next().is_none());
|
||||
Ok((Request::ListPlaylists, ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
46
src/commands/stored_playlists/load.rs
Normal file
46
src/commands/stored_playlists/load.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Load;
|
||||
|
||||
impl Command for Load {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "load";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let mut range = None;
|
||||
let mut pos = None;
|
||||
|
||||
for _ in 0..2 {
|
||||
if let Some(range_or_pos) = parts.next() {
|
||||
if range_or_pos.contains(':') {
|
||||
range = Some(range_or_pos.parse().map_err(|_| {
|
||||
RequestParserError::SyntaxError(0, range_or_pos.to_owned())
|
||||
})?);
|
||||
} else {
|
||||
pos = Some(range_or_pos.parse().map_err(|_| {
|
||||
RequestParserError::SyntaxError(0, range_or_pos.to_owned())
|
||||
})?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Load(playlist_name, range, pos), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
42
src/commands/stored_playlists/playlistadd.rs
Normal file
42
src/commands/stored_playlists/playlistadd.rs
Normal file
@ -0,0 +1,42 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct PlaylistAdd;
|
||||
|
||||
impl Command for PlaylistAdd {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "playlistadd";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let uri = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let position = parts
|
||||
.next()
|
||||
.map(|s| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::PlaylistAdd(playlist_name, uri, position), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
29
src/commands/stored_playlists/playlistclear.rs
Normal file
29
src/commands/stored_playlists/playlistclear.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct PlaylistClear;
|
||||
|
||||
impl Command for PlaylistClear {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "playlistclear";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::PlaylistClear(playlist_name), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
35
src/commands/stored_playlists/playlistdelete.rs
Normal file
35
src/commands/stored_playlists/playlistdelete.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct PlaylistDelete;
|
||||
|
||||
impl Command for PlaylistDelete {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "playlistdelete";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
// TODO: this can be a range, according to docs
|
||||
let position = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let position = position
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, position.to_string()))?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::PlaylistDelete(playlist_name, position), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
40
src/commands/stored_playlists/playlistlength.rs
Normal file
40
src/commands/stored_playlists/playlistlength.rs
Normal file
@ -0,0 +1,40 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::commands::{
|
||||
get_and_parse_property, Command, Request, RequestParserError, RequestParserResult,
|
||||
ResponseAttributes, ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct PlaylistLength;
|
||||
|
||||
pub struct PlaylistLengthResponse {
|
||||
pub songs: u64,
|
||||
pub playtime: u64,
|
||||
}
|
||||
|
||||
impl Command for PlaylistLength {
|
||||
type Response = PlaylistLengthResponse;
|
||||
const COMMAND: &'static str = "playlistlength";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::PlaylistLength(playlist_name), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
let parts: HashMap<_, _> = parts.into();
|
||||
|
||||
let songs = get_and_parse_property!(parts, "songs", Text);
|
||||
let playtime = get_and_parse_property!(parts, "playtime", Text);
|
||||
|
||||
Ok(PlaylistLengthResponse { songs, playtime })
|
||||
}
|
||||
}
|
46
src/commands/stored_playlists/playlistmove.rs
Normal file
46
src/commands/stored_playlists/playlistmove.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct PlaylistMove;
|
||||
|
||||
impl Command for PlaylistMove {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "playlistmove";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let mut from = None;
|
||||
let from_or_range_or_to = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
|
||||
let to = parts.next();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
let to = if let Some(to) = to {
|
||||
from = Some(from_or_range_or_to.parse().map_err(|_| {
|
||||
RequestParserError::SyntaxError(0, from_or_range_or_to.to_string())
|
||||
})?);
|
||||
to.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, to.to_string()))?
|
||||
} else {
|
||||
from_or_range_or_to
|
||||
.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, from_or_range_or_to.to_string()))?
|
||||
};
|
||||
|
||||
Ok((Request::PlaylistMove(playlist_name, from, to), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
34
src/commands/stored_playlists/rename.rs
Normal file
34
src/commands/stored_playlists/rename.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Rename;
|
||||
|
||||
impl Command for Rename {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "rename";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let old_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let new_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Rename(old_name, new_name), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
29
src/commands/stored_playlists/rm.rs
Normal file
29
src/commands/stored_playlists/rm.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Rm;
|
||||
|
||||
impl Command for Rm {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "rm";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Rm(playlist_name), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
37
src/commands/stored_playlists/save.rs
Normal file
37
src/commands/stored_playlists/save.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use crate::commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
};
|
||||
|
||||
pub struct Save;
|
||||
|
||||
impl Command for Save {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "save";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let playlist_name = parts
|
||||
.next()
|
||||
.ok_or(RequestParserError::UnexpectedEOF)?
|
||||
.to_string();
|
||||
|
||||
let mode = parts
|
||||
.next()
|
||||
.map(|m| {
|
||||
m.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, m.to_string()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::Save(playlist_name, mode), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
debug_assert!(parts.is_empty());
|
||||
Ok(())
|
||||
}
|
||||
}
|
44
src/commands/stored_playlists/searchplaylist.rs
Normal file
44
src/commands/stored_playlists/searchplaylist.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::{
|
||||
commands::{
|
||||
Command, Request, RequestParserError, RequestParserResult, ResponseAttributes,
|
||||
ResponseParserError,
|
||||
},
|
||||
common::{Filter, PlaylistName},
|
||||
};
|
||||
|
||||
pub struct SearchPlaylist;
|
||||
|
||||
impl Command for SearchPlaylist {
|
||||
type Response = ();
|
||||
const COMMAND: &'static str = "searchplaylist";
|
||||
|
||||
fn parse_request(mut parts: std::str::SplitWhitespace<'_>) -> RequestParserResult<'_> {
|
||||
let name = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let name = name
|
||||
.parse::<PlaylistName>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, name.to_owned()))?;
|
||||
|
||||
let filter = parts.next().ok_or(RequestParserError::UnexpectedEOF)?;
|
||||
let filter = filter
|
||||
.parse::<Filter>()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, filter.to_owned()))?;
|
||||
|
||||
let range = parts
|
||||
.next()
|
||||
.map(|s| {
|
||||
s.parse()
|
||||
.map_err(|_| RequestParserError::SyntaxError(0, s.to_owned()))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
debug_assert!(parts.next().is_none());
|
||||
|
||||
Ok((Request::SearchPlaylist(name, filter, range), ""))
|
||||
}
|
||||
|
||||
fn parse_response(
|
||||
parts: ResponseAttributes<'_>,
|
||||
) -> Result<Self::Response, ResponseParserError> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
@ -80,13 +80,13 @@ pub enum Request {
|
||||
ListPlaylistInfo(PlaylistName, Option<WindowRange>),
|
||||
SearchPlaylist(PlaylistName, Filter, Option<WindowRange>),
|
||||
ListPlaylists,
|
||||
Load(PlaylistName, Option<WindowRange>, SongPosition),
|
||||
PlaylistAdd(PlaylistName, Uri, SongPosition),
|
||||
Load(PlaylistName, Option<WindowRange>, Option<SongPosition>),
|
||||
PlaylistAdd(PlaylistName, Uri, Option<SongPosition>),
|
||||
PlaylistClear(PlaylistName),
|
||||
PlaylistDelete(PlaylistName, OneOrRange),
|
||||
PlaylistLength(PlaylistName),
|
||||
// TODO: which type of range?
|
||||
PlaylistMove(PlaylistName, OneOrRange, SongPosition),
|
||||
PlaylistMove(PlaylistName, Option<OneOrRange>, SongPosition),
|
||||
Rename(PlaylistName, PlaylistName),
|
||||
Rm(PlaylistName),
|
||||
Save(PlaylistName, Option<SaveMode>),
|
||||
@ -129,7 +129,7 @@ pub enum Request {
|
||||
Rescan(Option<Uri>),
|
||||
|
||||
// -- Mount and Neighbor Commands -- //
|
||||
Mount(Option<Path>, Option<Uri>),
|
||||
Mount(Path, Uri),
|
||||
Unmount(Path),
|
||||
ListMounts,
|
||||
ListNeighbors,
|
||||
@ -159,12 +159,12 @@ pub enum Request {
|
||||
Ping,
|
||||
BinaryLimit(u64),
|
||||
TagTypes,
|
||||
TagTypesDisable(Vec<Tag>),
|
||||
TagTypesEnable(Vec<Tag>),
|
||||
TagTypesDisable(Vec<TagName>),
|
||||
TagTypesEnable(Vec<TagName>),
|
||||
TagTypesClear,
|
||||
TagTypesAll,
|
||||
TagTypesAvailable,
|
||||
TagTypesReset(Vec<Tag>),
|
||||
TagTypesReset(Vec<TagName>),
|
||||
Protocol,
|
||||
ProtocolDisable(Vec<Feature>),
|
||||
ProtocolEnable(Vec<Feature>),
|
||||
@ -410,16 +410,56 @@ impl Request {
|
||||
ClearTagId::COMMAND => ClearTagId::parse_request(parts),
|
||||
|
||||
/* stored playlists */
|
||||
ListPlaylist::COMMAND => ListPlaylist::parse_request(parts),
|
||||
ListPlaylistInfo::COMMAND => ListPlaylistInfo::parse_request(parts),
|
||||
SearchPlaylist::COMMAND => SearchPlaylist::parse_request(parts),
|
||||
ListPlaylists::COMMAND => ListPlaylists::parse_request(parts),
|
||||
Load::COMMAND => Load::parse_request(parts),
|
||||
PlaylistAdd::COMMAND => PlaylistAdd::parse_request(parts),
|
||||
PlaylistClear::COMMAND => PlaylistClear::parse_request(parts),
|
||||
PlaylistDelete::COMMAND => PlaylistDelete::parse_request(parts),
|
||||
PlaylistLength::COMMAND => PlaylistLength::parse_request(parts),
|
||||
PlaylistMove::COMMAND => PlaylistMove::parse_request(parts),
|
||||
Rename::COMMAND => Rename::parse_request(parts),
|
||||
Rm::COMMAND => Rm::parse_request(parts),
|
||||
Save::COMMAND => Save::parse_request(parts),
|
||||
|
||||
/* music database */
|
||||
|
||||
/* mounts and neighbors */
|
||||
Mount::COMMAND => Mount::parse_request(parts),
|
||||
Unmount::COMMAND => Unmount::parse_request(parts),
|
||||
ListMounts::COMMAND => ListMounts::parse_request(parts),
|
||||
ListNeighbors::COMMAND => ListNeighbors::parse_request(parts),
|
||||
|
||||
/* stickers */
|
||||
|
||||
/* connection settings */
|
||||
Close::COMMAND => Close::parse_request(parts),
|
||||
Kill::COMMAND => Kill::parse_request(parts),
|
||||
Password::COMMAND => Password::parse_request(parts),
|
||||
Ping::COMMAND => Ping::parse_request(parts),
|
||||
BinaryLimit::COMMAND => BinaryLimit::parse_request(parts),
|
||||
TagTypes::COMMAND => TagTypes::parse_request(parts),
|
||||
TagTypesDisable::COMMAND => TagTypesDisable::parse_request(parts),
|
||||
TagTypesEnable::COMMAND => TagTypesEnable::parse_request(parts),
|
||||
TagTypesClear::COMMAND => TagTypesClear::parse_request(parts),
|
||||
TagTypesAll::COMMAND => TagTypesAll::parse_request(parts),
|
||||
TagTypesAvailable::COMMAND => TagTypesAvailable::parse_request(parts),
|
||||
TagTypesReset::COMMAND => TagTypesReset::parse_request(parts),
|
||||
Protocol::COMMAND => Protocol::parse_request(parts),
|
||||
ProtocolDisable::COMMAND => ProtocolDisable::parse_request(parts),
|
||||
ProtocolEnable::COMMAND => ProtocolEnable::parse_request(parts),
|
||||
ProtocolClear::COMMAND => ProtocolClear::parse_request(parts),
|
||||
ProtocolAll::COMMAND => ProtocolAll::parse_request(parts),
|
||||
ProtocolAvailable::COMMAND => ProtocolAvailable::parse_request(parts),
|
||||
|
||||
/* partition commands */
|
||||
Partition::COMMAND => Partition::parse_request(parts),
|
||||
ListPartitions::COMMAND => ListPartitions::parse_request(parts),
|
||||
NewPartition::COMMAND => NewPartition::parse_request(parts),
|
||||
DelPartition::COMMAND => DelPartition::parse_request(parts),
|
||||
MoveOutput::COMMAND => MoveOutput::parse_request(parts),
|
||||
|
||||
/* audio output devices */
|
||||
DisableOutput::COMMAND => DisableOutput::parse_request(parts),
|
||||
@ -429,6 +469,11 @@ impl Request {
|
||||
OutputSet::COMMAND => OutputSet::parse_request(parts),
|
||||
|
||||
/* reflection */
|
||||
Config::COMMAND => Config::parse_request(parts),
|
||||
Commands::COMMAND => Commands::parse_request(parts),
|
||||
NotCommands::COMMAND => NotCommands::parse_request(parts),
|
||||
UrlHandlers::COMMAND => UrlHandlers::parse_request(parts),
|
||||
Decoders::COMMAND => Decoders::parse_request(parts),
|
||||
|
||||
/* client to client */
|
||||
Subscribe::COMMAND => Subscribe::parse_request(parts),
|
||||
|
Loading…
Reference in New Issue
Block a user