Lines
0 %
Functions
//! A high-level client for interacting with an Mpd server.
//!
//! The client provides methods for common operations such as playing, pausing, and
//! managing the playlist, and returns the expected response types directly
//! from its methods.
use crate::{Request, commands::*, types::SongPosition};
#[cfg(feature = "futures")]
use futures_util::{
AsyncBufReadExt,
io::{AsyncRead, AsyncWrite, AsyncWriteExt, BufReader},
};
use thiserror::Error;
#[cfg(feature = "tokio")]
use tokio::io::{AsyncBufReadExt, AsyncRead, AsyncWrite, AsyncWriteExt, BufReader};
pub struct MpdClient<'a, T>
where
T: AsyncWrite + AsyncRead + Unpin,
{
connection: &'a mut T,
}
#[derive(Error, Debug)]
pub enum MpdClientError {
#[error("Connection error: {0}")]
ConnectionError(#[from] std::io::Error),
#[error("Failed to parse MPD response: {0}")]
ResponseParseError(#[from] crate::commands::ResponseParserError),
#[error("MPD returned an error: {0}")]
MpdError(#[from] crate::response::MpdError),
impl<'a, T> MpdClient<'a, T>
pub fn new(connection: &'a mut T) -> Self {
MpdClient { connection }
pub async fn read_initial_mpd_version(&mut self) -> Result<String, MpdClientError> {
let mut reader = BufReader::new(&mut self.connection);
let mut version_line = String::new();
reader
.read_line(&mut version_line)
.await
.map_err(MpdClientError::ConnectionError)?;
Ok(version_line.trim().to_string())
async fn read_response(&mut self) -> Result<Vec<u8>, MpdClientError> {
let mut response = Vec::new();
loop {
let mut line = Vec::new();
let bytes_read = reader
.read_until(b'\n', &mut line)
if bytes_read == 0 {
break; // EOF reached
response.extend_from_slice(&line);
if line == b"OK\n" || line.starts_with(b"ACK ") {
break; // End of response
Ok(response)
pub async fn play(
&mut self,
position: Option<SongPosition>,
) -> Result<PlayResponse, MpdClientError> {
let message = Request::Play(position);
let payload = message.serialize();
self.connection
.write_all(payload.as_bytes())
.flush()
let response_bytes = self.read_response().await?;
let response = PlayResponse::parse_raw(&response_bytes)?;