diff --git a/mpd_client/src/commands/definitions.rs b/mpd_client/src/commands/definitions.rs index 137277f..e7f60ed 100644 --- a/mpd_client/src/commands/definitions.rs +++ b/mpd_client/src/commands/definitions.rs @@ -14,7 +14,7 @@ use mpd_protocol::{ }; use crate::{ - commands::{Command, SeekMode, SingleMode, Song, SongId, SongPosition}, + commands::{Command, ReplayGainMode, SeekMode, SingleMode, Song, SongId, SongPosition}, filter::Filter, responses::{self as res, value, TypedResponseError}, tag::Tag, @@ -94,6 +94,22 @@ single_arg_command!(SetRepeat, bool, "repeat"); single_arg_command!(SubscribeToChannel<'a>, &'a str, "subscribe"); single_arg_command!(UnsubscribeFromChannel<'a>, &'a str, "unsubscribe"); +/// `replay_gain_status` command. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct ReplayGainStatus; + +impl Command for ReplayGainStatus { + type Response = res::ReplayGainStatus; + + fn command(&self) -> RawCommand { + RawCommand::new("replay_gain_status") + } + + fn response(self, frame: Frame) -> Result { + res::ReplayGainStatus::from_frame(frame) + } +} + /// `status` command. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Status; @@ -262,6 +278,29 @@ impl Command for SetSingle { } } +/// 'replay_gain_mode' command +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct SetReplayGainMode(pub ReplayGainMode); + +impl Command for SetReplayGainMode { + type Response = (); + + fn command(&self) -> RawCommand { + let rgm = match self.0 { + ReplayGainMode::Off => "off", + ReplayGainMode::Track => "track", + ReplayGainMode::Album => "album", + ReplayGainMode::Auto => "auto", + }; + + RawCommand::new("replay_gain_mode").argument(rgm) + } + + fn response(self, _: Frame) -> Result { + Ok(()) + } +} + /// `crossfade` command. /// /// The given duration is rounded down to whole seconds. diff --git a/mpd_client/src/commands/mod.rs b/mpd_client/src/commands/mod.rs index d201dae..e896d62 100644 --- a/mpd_client/src/commands/mod.rs +++ b/mpd_client/src/commands/mod.rs @@ -77,6 +77,20 @@ pub enum SingleMode { Oneshot, } +/// Possible `replay_gain_mode` modes. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[allow(missing_docs)] +pub enum ReplayGainMode { + /// Replay Gain off + Off, + /// Replay Gain Track mode + Track, + /// Replay Gain Album mode + Album, + /// Replay Gain Track if shuffle is on, Album otherwise + Auto, +} + /// Modes to target a song with a command. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Song { diff --git a/mpd_client/src/responses/mod.rs b/mpd_client/src/responses/mod.rs index 852fd8e..8e14e54 100644 --- a/mpd_client/src/responses/mod.rs +++ b/mpd_client/src/responses/mod.rs @@ -20,7 +20,7 @@ pub use self::{ sticker::{StickerFind, StickerGet, StickerList}, timestamp::Timestamp, }; -use crate::commands::{SingleMode, SongId, SongPosition}; +use crate::commands::{ReplayGainMode, SingleMode, SongId, SongPosition}; type KeyValuePair = (Arc, String); @@ -157,6 +157,18 @@ impl FromFieldValue for PlayState { } } +impl FromFieldValue for ReplayGainMode { + fn from_value(v: String, field: &str) -> Result { + match &*v { + "off" => Ok(ReplayGainMode::Off), + "track" => Ok(ReplayGainMode::Track), + "album" => Ok(ReplayGainMode::Album), + "auto" => Ok(ReplayGainMode::Auto), + _ => Err(TypedResponseError::invalid_value(field, v)), + } + } +} + fn parse_integer>( v: String, field: &str, @@ -257,6 +269,28 @@ pub enum PlayState { Paused, } +/// Response to the [`replay_gain_status`] command. +/// +/// See the [MPD documentation][replay-gain-status-command] for the specific meanings of the fields. +/// +/// [`replay_gain_status`]: crate::commands::definitions::ReplayGainStatus +/// [replay-gain-status-command]: https://www.musicpd.org/doc/html/protocol.html#command-replay-gain-status +#[derive(Clone, Debug, PartialEq, Eq)] +#[allow(missing_docs)] +#[non_exhaustive] +pub struct ReplayGainStatus { + pub mode: ReplayGainMode, +} + +impl ReplayGainStatus { + pub(crate) fn from_frame(mut raw: Frame) -> Result { + let f = &mut raw; + Ok(Self { + mode: value(f, "replay_gain_mode")?, + }) + } +} + /// Response to the [`status`] command. /// /// See the [MPD documentation][status-command] for the specific meanings of the fields.