commands: add command executor directly on Command trait
This commit is contained in:
@@ -37,6 +37,16 @@ pub use reflection::*;
|
||||
pub use stickers::*;
|
||||
pub use stored_playlists::*;
|
||||
|
||||
#[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};
|
||||
|
||||
/// A trait modelling a single MPD command request.
|
||||
pub trait CommandRequest
|
||||
where
|
||||
@@ -159,6 +169,55 @@ pub trait Command {
|
||||
fn parse_raw_response(raw: &[u8]) -> Result<Self::Response, ResponseParserError> {
|
||||
Self::Response::parse_raw(raw)
|
||||
}
|
||||
|
||||
async fn execute<T>(
|
||||
request: Self::Request,
|
||||
connection: &mut T,
|
||||
) -> Result<Self::Response, crate::MpdClientError>
|
||||
where
|
||||
Self: Sized,
|
||||
T: AsyncWrite + AsyncRead + Unpin,
|
||||
{
|
||||
let payload = request.serialize();
|
||||
|
||||
connection
|
||||
.write_all(payload.as_bytes())
|
||||
.await
|
||||
.map_err(crate::MpdClientError::ConnectionError)?;
|
||||
|
||||
connection
|
||||
.flush()
|
||||
.await
|
||||
.map_err(crate::MpdClientError::ConnectionError)?;
|
||||
|
||||
let mut response_bytes = Vec::new();
|
||||
let mut reader = BufReader::new(connection);
|
||||
|
||||
loop {
|
||||
let mut line = Vec::new();
|
||||
|
||||
let bytes_read = reader
|
||||
.read_until(b'\n', &mut line)
|
||||
.await
|
||||
.map_err(crate::MpdClientError::ConnectionError)?;
|
||||
|
||||
if bytes_read == 0 {
|
||||
break; // EOF reached
|
||||
}
|
||||
|
||||
response_bytes.extend_from_slice(&line);
|
||||
|
||||
// TODO: handle errors properly
|
||||
if line == b"OK\n" || line.starts_with(b"ACK ") {
|
||||
break; // End of response
|
||||
}
|
||||
}
|
||||
|
||||
let response = Self::parse_raw_response(&response_bytes)
|
||||
.map_err(crate::MpdClientError::ResponseParseError)?;
|
||||
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
|
||||
// Request/response implementation helpers
|
||||
|
||||
Reference in New Issue
Block a user