Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
5a74dd0b02 | |||
ee5aa30335 | |||
e3297bef15 | |||
00cae63272 | |||
99884b670d | |||
3fe7417d4c | |||
eb7277e4fd | |||
81479d2f64 | |||
b2a22a9a57 | |||
ac863c571e | |||
13397a59f7 | |||
be5c37b433 | |||
3ca3d7784c | |||
fa937567bd | |||
c129e5104d |
@ -7,37 +7,26 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest-personal
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install latest nightly toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Install rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Build
|
||||
run: cargo build --all-features --verbose --release
|
||||
|
||||
check:
|
||||
runs-on: ubuntu-latest-personal
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install latest nightly toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Install rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Check code format
|
||||
run: cargo fmt -- --check
|
||||
|
||||
@ -45,30 +34,27 @@ jobs:
|
||||
run: cargo clippy --all-features -- --deny warnings
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest-personal
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: cargo-bins/cargo-binstall@main
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install cargo binstall
|
||||
uses: cargo-bins/cargo-binstall@main
|
||||
|
||||
- name: Install mpv
|
||||
run: apt-get update && apt-get install -y mpv
|
||||
|
||||
- name: Install latest nightly toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
- name: Install rust toolchain
|
||||
uses: dtolnay/rust-toolchain@nightly
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
components: llvm-tools-preview
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
|
||||
- name: Install nextest
|
||||
run: cargo binstall -y cargo-nextest --secure
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cargo nextest run --all-features --release --no-fail-fast
|
||||
cargo nextest run --all-features --release --no-fail-fast --test-threads=1
|
||||
env:
|
||||
RUST_LOG: "trace"
|
||||
RUSTFLAGS: "-Cinstrument-coverage"
|
||||
@ -96,38 +82,32 @@ jobs:
|
||||
target/coverage/
|
||||
|
||||
- name: Upload test report
|
||||
uses: https://git.pvv.ntnu.no/oysteikt/rsync-action@main
|
||||
uses: https://git.pvv.ntnu.no/Projects/rsync-action@v1
|
||||
with:
|
||||
source: target/coverage/html/
|
||||
target: mpvipc-async/${{ gitea.ref_name }}/coverage/
|
||||
username: oysteikt
|
||||
ssh-key: ${{ secrets.OYSTEIKT_GITEA_WEBDOCS_SSH_KEY }}
|
||||
host: microbel.pvv.ntnu.no
|
||||
known-hosts: "microbel.pvv.ntnu.no ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEq0yasKP0mH6PI6ypmuzPzMnbHELo9k+YB5yW534aKudKZS65YsHJKQ9vapOtmegrn5MQbCCgrshf+/XwZcjbM="
|
||||
target: ${{ gitea.ref_name }}/coverage/
|
||||
username: gitea-web
|
||||
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
|
||||
host: bekkalokk.pvv.ntnu.no
|
||||
known-hosts: "bekkalokk.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEI6VSaDrMG8+flg4/AeHlAFIen8RUzWh6URQKqFegSx"
|
||||
|
||||
docs:
|
||||
runs-on: ubuntu-latest-personal
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install latest nightly toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
override: true
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
- name: Install rust toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Build docs
|
||||
run: cargo doc --all-features --document-private-items --release
|
||||
|
||||
- name: Transfer files
|
||||
uses: https://git.pvv.ntnu.no/oysteikt/rsync-action@main
|
||||
uses: https://git.pvv.ntnu.no/Projects/rsync-action@v1
|
||||
with:
|
||||
source: target/doc/
|
||||
target: mpvipc-async/${{ gitea.ref_name }}/docs/
|
||||
username: oysteikt
|
||||
ssh-key: ${{ secrets.OYSTEIKT_GITEA_WEBDOCS_SSH_KEY }}
|
||||
host: microbel.pvv.ntnu.no
|
||||
known-hosts: "microbel.pvv.ntnu.no ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEq0yasKP0mH6PI6ypmuzPzMnbHELo9k+YB5yW534aKudKZS65YsHJKQ9vapOtmegrn5MQbCCgrshf+/XwZcjbM="
|
||||
target: ${{ gitea.ref_name }}/docs/
|
||||
username: gitea-web
|
||||
ssh-key: ${{ secrets.WEB_SYNC_SSH_KEY }}
|
||||
host: bekkalokk.pvv.ntnu.no
|
||||
known-hosts: "bekkalokk.pvv.ntnu.no ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEI6VSaDrMG8+flg4/AeHlAFIen8RUzWh6URQKqFegSx"
|
||||
|
@ -7,9 +7,8 @@ authors = [
|
||||
]
|
||||
description = "A small library which provides bindings to control existing mpv instances through sockets."
|
||||
license = "GPL-3.0"
|
||||
homepage = "https://git.pvv.ntnu.no/oysteikt/mpvipc-async"
|
||||
repository = "https://git.pvv.ntnu.no/oysteikt/mpvipc-async"
|
||||
documentation = "https://pvv.ntnu.no/~oysteikt/gitea/mpvipc-async/master/docs/mpvipc-async/"
|
||||
repository = "https://git.pvv.ntnu.no/Projects/mpvipc-async"
|
||||
documentation = "https://pages.pvv.ntnu.no/Projects/mpvipc-async/main/docs/mpvipc_async/"
|
||||
edition = "2021"
|
||||
rust-version = "1.75"
|
||||
|
||||
|
@ -1,11 +1,10 @@
|
||||
[![Coverage](https://pvv.ntnu.no/~oysteikt/gitea/mpvipc-async/main/coverage/badges/for_the_badge.svg)](https://pvv.ntnu.no/~oysteikt/gitea/mpvipc-async/main/coverage/src/)
|
||||
[![Docs](https://img.shields.io/badge/docs-blue?style=for-the-badge&logo=rust)](https://pvv.ntnu.no/~oysteikt/gitea/mpvipc-async/main/docs/mpvipc_async/)
|
||||
[![Coverage](https://pages.pvv.ntnu.no/Projects/mpvipc-async/main/coverage/badges/for_the_badge.svg)](https://pages.pvv.ntnu.no/Projects/mpvipc-async/main/coverage/src/)
|
||||
[![Docs](https://img.shields.io/badge/docs-blue?style=for-the-badge&logo=rust)](https://pages.pvv.ntnu.no/Projects/mpvipc-async/main/docs/mpvipc_async/)
|
||||
|
||||
# mpvipc-async
|
||||
|
||||
> **NOTE:** This is a fork of [gitlab.com/mpv-ipc/mpvipc](https://gitlab.com/mpv-ipc/mpvipc), which introduces a lot of changes to be able to use the library asynchronously with [tokio](https://github.com/tokio-rs/tokio).
|
||||
|
||||
---
|
||||
|
||||
A small library which provides bindings to control existing mpv instances through sockets.
|
||||
|
||||
@ -34,4 +33,4 @@ async fn main() -> Result<(), MpvError> {
|
||||
let paused: bool = mpv.get_property("pause").await?;
|
||||
mpv.set_property("pause", !paused).await.expect("Error pausing");
|
||||
}
|
||||
```
|
||||
```
|
||||
|
@ -27,39 +27,65 @@ use crate::{
|
||||
/// the upstream list of commands.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum MpvCommand {
|
||||
/// Load the given file or URL and play it.
|
||||
LoadFile {
|
||||
file: String,
|
||||
option: PlaylistAddOptions,
|
||||
},
|
||||
|
||||
/// Load the given playlist file or URL.
|
||||
LoadList {
|
||||
file: String,
|
||||
option: PlaylistAddOptions,
|
||||
},
|
||||
|
||||
/// Clear the playlist, except for the currently playing file.
|
||||
PlaylistClear,
|
||||
PlaylistMove {
|
||||
from: usize,
|
||||
to: usize,
|
||||
},
|
||||
Observe {
|
||||
id: usize,
|
||||
property: String,
|
||||
},
|
||||
|
||||
///Move the playlist entry at `from`, so that it takes the place of the entry `to`.
|
||||
/// (Paradoxically, the moved playlist entry will not have the index value `to` after moving
|
||||
/// if `from` was lower than `to`, because `to` refers to the target entry, not the index
|
||||
/// the entry will have after moving.)
|
||||
PlaylistMove { from: usize, to: usize },
|
||||
|
||||
/// Observe a property. This will start triggering [`Event::PropertyChange`] events
|
||||
/// in the event stream whenever the specific property changes.
|
||||
/// You can use [`Mpv::get_event_stream`] to get the stream.
|
||||
Observe { id: u64, property: String },
|
||||
|
||||
/// Skip to the next entry in the playlist.
|
||||
PlaylistNext,
|
||||
|
||||
/// Skip to the previous entry in the playlist.
|
||||
PlaylistPrev,
|
||||
|
||||
/// Remove an entry from the playlist by its position in the playlist.
|
||||
PlaylistRemove(usize),
|
||||
|
||||
/// Shuffle the playlist
|
||||
PlaylistShuffle,
|
||||
|
||||
/// Exit the player
|
||||
Quit,
|
||||
|
||||
/// Send a message to all clients, and pass it the following list of arguments.
|
||||
/// What this message means, how many arguments it takes, and what the arguments
|
||||
/// mean is fully up to the receiver and the sender.
|
||||
ScriptMessage(Vec<String>),
|
||||
ScriptMessageTo {
|
||||
target: String,
|
||||
args: Vec<String>,
|
||||
},
|
||||
Seek {
|
||||
seconds: f64,
|
||||
option: SeekOptions,
|
||||
},
|
||||
|
||||
/// Same as [`MpvCommand::ScriptMessage`], but send the message to a specific target.
|
||||
ScriptMessageTo { target: String, args: Vec<String> },
|
||||
|
||||
/// Change the playback position.
|
||||
Seek { seconds: f64, option: SeekOptions },
|
||||
|
||||
/// Stop the current playback, and clear the playlist.
|
||||
/// This esentially resets the entire player state without exiting mpv.
|
||||
Stop,
|
||||
Unobserve(usize),
|
||||
|
||||
/// Unobserve all properties registered with the given id.
|
||||
/// See [`MpvCommand::Observe`] for more context.
|
||||
Unobserve(u64),
|
||||
}
|
||||
|
||||
/// Helper trait to keep track of the string literals that mpv expects.
|
||||
@ -69,6 +95,7 @@ pub(crate) trait IntoRawCommandPart {
|
||||
|
||||
/// Generic data type representing all possible data types that mpv can return.
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum MpvDataType {
|
||||
Array(Vec<MpvDataType>),
|
||||
Bool(bool),
|
||||
@ -82,7 +109,7 @@ pub enum MpvDataType {
|
||||
}
|
||||
|
||||
/// A mpv playlist.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
|
||||
pub struct Playlist(pub Vec<PlaylistEntry>);
|
||||
|
||||
/// A single entry in the mpv playlist.
|
||||
|
18
src/error.rs
18
src/error.rs
@ -8,8 +8,11 @@ use crate::{MpvDataType, Property};
|
||||
/// Any error that can occur when interacting with mpv.
|
||||
#[derive(Error, Debug)]
|
||||
pub enum MpvError {
|
||||
#[error("MpvError: {0}")]
|
||||
MpvError(String),
|
||||
#[error("Mpv returned error in response to command: {message}\nCommand: {command:#?}")]
|
||||
MpvError {
|
||||
command: Vec<Value>,
|
||||
message: String,
|
||||
},
|
||||
|
||||
#[error("Error communicating over mpv socket: {0}")]
|
||||
MpvSocketConnectionError(String),
|
||||
@ -53,7 +56,16 @@ pub enum MpvError {
|
||||
impl PartialEq for MpvError {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (self, other) {
|
||||
(Self::MpvError(l0), Self::MpvError(r0)) => l0 == r0,
|
||||
(
|
||||
Self::MpvError {
|
||||
command: l_command,
|
||||
message: l_message,
|
||||
},
|
||||
Self::MpvError {
|
||||
command: r_command,
|
||||
message: r_message,
|
||||
},
|
||||
) => l_command == r_command && l_message == r_message,
|
||||
(Self::MpvSocketConnectionError(l0), Self::MpvSocketConnectionError(r0)) => l0 == r0,
|
||||
(Self::InternalConnectionError(l0), Self::InternalConnectionError(r0)) => l0 == r0,
|
||||
(Self::JsonParseError(l0), Self::JsonParseError(r0)) => {
|
||||
|
@ -109,7 +109,7 @@ pub enum Event {
|
||||
VideoReconfig,
|
||||
AudioReconfig,
|
||||
PropertyChange {
|
||||
id: usize,
|
||||
id: Option<u64>,
|
||||
name: String,
|
||||
data: Option<MpvDataType>,
|
||||
},
|
||||
@ -296,7 +296,7 @@ fn parse_client_message(event: &Map<String, Value>) -> Result<Event, MpvError> {
|
||||
}
|
||||
|
||||
fn parse_property_change(event: &Map<String, Value>) -> Result<Event, MpvError> {
|
||||
let id = get_key_as!(as_u64, "id", event) as usize;
|
||||
let id = get_optional_key_as!(as_u64, "id", event);
|
||||
let property_name = get_key_as!(as_str, "name", event);
|
||||
let data = event.get("data").map(json_to_value).transpose()?;
|
||||
|
||||
|
@ -88,11 +88,11 @@ pub trait MpvExt {
|
||||
|
||||
/// Notify mpv to send events whenever a property changes.
|
||||
/// See [`Mpv::get_event_stream`] and [`Property`](crate::Property) for more information.
|
||||
async fn observe_property(&self, id: usize, property: &str) -> Result<(), MpvError>;
|
||||
async fn observe_property(&self, id: u64, property: &str) -> Result<(), MpvError>;
|
||||
|
||||
/// Stop observing a property.
|
||||
/// See [`Mpv::get_event_stream`] and [`Property`](crate::Property) for more information.
|
||||
async fn unobserve_property(&self, id: usize) -> Result<(), MpvError>;
|
||||
async fn unobserve_property(&self, id: u64) -> Result<(), MpvError>;
|
||||
|
||||
/// Skip to the next entry in the playlist.
|
||||
async fn next(&self) -> Result<(), MpvError>;
|
||||
@ -259,7 +259,7 @@ impl MpvExt for Mpv {
|
||||
self.run_command(MpvCommand::PlaylistPrev).await
|
||||
}
|
||||
|
||||
async fn observe_property(&self, id: usize, property: &str) -> Result<(), MpvError> {
|
||||
async fn observe_property(&self, id: u64, property: &str) -> Result<(), MpvError> {
|
||||
self.run_command(MpvCommand::Observe {
|
||||
id,
|
||||
property: property.to_string(),
|
||||
@ -267,7 +267,7 @@ impl MpvExt for Mpv {
|
||||
.await
|
||||
}
|
||||
|
||||
async fn unobserve_property(&self, id: usize) -> Result<(), MpvError> {
|
||||
async fn unobserve_property(&self, id: u64) -> Result<(), MpvError> {
|
||||
self.run_command(MpvCommand::Unobserve(id)).await
|
||||
}
|
||||
|
||||
@ -323,9 +323,9 @@ impl MpvExt for Mpv {
|
||||
Switch::Off => "yes",
|
||||
Switch::Toggle => {
|
||||
if self.is_playing().await? {
|
||||
"no"
|
||||
} else {
|
||||
"yes"
|
||||
} else {
|
||||
"no"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
20
src/ipc.rs
20
src/ipc.rs
@ -24,8 +24,8 @@ pub(crate) enum MpvIpcCommand {
|
||||
Command(Vec<String>),
|
||||
GetProperty(String),
|
||||
SetProperty(String, Value),
|
||||
ObserveProperty(usize, String),
|
||||
UnobserveProperty(usize),
|
||||
ObserveProperty(u64, String),
|
||||
UnobserveProperty(u64),
|
||||
Exit,
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ impl MpvIpc {
|
||||
|
||||
log::trace!("Received response: {:?}", response);
|
||||
|
||||
parse_mpv_response_data(response?)
|
||||
parse_mpv_response_data(response?, command)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_mpv_property(
|
||||
@ -114,17 +114,14 @@ impl MpvIpc {
|
||||
|
||||
pub(crate) async fn observe_property(
|
||||
&mut self,
|
||||
id: usize,
|
||||
id: u64,
|
||||
property: &str,
|
||||
) -> Result<Option<Value>, MpvError> {
|
||||
self.send_command(&[json!("observe_property"), json!(id), json!(property)])
|
||||
.await
|
||||
}
|
||||
|
||||
pub(crate) async fn unobserve_property(
|
||||
&mut self,
|
||||
id: usize,
|
||||
) -> Result<Option<Value>, MpvError> {
|
||||
pub(crate) async fn unobserve_property(&mut self, id: u64) -> Result<Option<Value>, MpvError> {
|
||||
self.send_command(&[json!("unobserve_property"), json!(id)])
|
||||
.await
|
||||
}
|
||||
@ -197,7 +194,7 @@ impl MpvIpc {
|
||||
/// This function does the most basic JSON parsing and error handling
|
||||
/// for status codes and errors that all responses from mpv are
|
||||
/// expected to contain.
|
||||
fn parse_mpv_response_data(value: Value) -> Result<Option<Value>, MpvError> {
|
||||
fn parse_mpv_response_data(value: Value, command: &[Value]) -> Result<Option<Value>, MpvError> {
|
||||
log::trace!("Parsing mpv response data: {:?}", value);
|
||||
let result = value
|
||||
.as_object()
|
||||
@ -225,7 +222,10 @@ fn parse_mpv_response_data(value: Value) -> Result<Option<Value>, MpvError> {
|
||||
.and_then(|(error, data)| match error {
|
||||
"success" => Ok(data),
|
||||
"property unavailable" => Ok(None),
|
||||
err => Err(MpvError::MpvError(err.to_string())),
|
||||
err => Err(MpvError::MpvError {
|
||||
command: command.to_owned(),
|
||||
message: err.to_string(),
|
||||
}),
|
||||
});
|
||||
|
||||
match &result {
|
||||
|
@ -1,5 +1,5 @@
|
||||
//! JSON parsing logic for properties returned by
|
||||
//! [[`Event::PropertyChange`], and used internally in `MpvExt`
|
||||
//! [`Event::PropertyChange`], and used internally in `MpvExt`
|
||||
//! to parse the response from `Mpv::get_property()`.
|
||||
//!
|
||||
//! This module is used to parse the json data from the `data` field of
|
||||
|
@ -8,7 +8,7 @@ use test_log::test;
|
||||
|
||||
use super::*;
|
||||
|
||||
const MPV_CHANNEL_ID: usize = 1337;
|
||||
const MPV_CHANNEL_ID: u64 = 1337;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
enum PropertyCheckingThreadError {
|
||||
@ -43,7 +43,7 @@ where
|
||||
match event {
|
||||
Some(Ok(event)) => {
|
||||
match event {
|
||||
Event::PropertyChange { id: MPV_CHANNEL_ID, name, data } => {
|
||||
Event::PropertyChange { id: Some(MPV_CHANNEL_ID), name, data } => {
|
||||
let property = parse_property(&name, data).unwrap();
|
||||
if !on_property(property.clone()) {
|
||||
return Err(PropertyCheckingThreadError::UnexpectedPropertyError(property))
|
||||
|
@ -47,10 +47,13 @@ async fn test_get_unavailable_property() -> Result<(), MpvError> {
|
||||
async fn test_get_nonexistent_property() -> Result<(), MpvError> {
|
||||
let (mut proc, mpv) = spawn_headless_mpv().await.unwrap();
|
||||
let nonexistent = mpv.get_property::<f64>("nonexistent").await;
|
||||
assert_eq!(
|
||||
nonexistent,
|
||||
Err(MpvError::MpvError("property not found".to_string()))
|
||||
);
|
||||
|
||||
match nonexistent {
|
||||
Err(MpvError::MpvError { message, .. }) => {
|
||||
assert_eq!(message, "property not found");
|
||||
}
|
||||
_ => panic!("Unexpected result: {:?}", nonexistent),
|
||||
}
|
||||
|
||||
mpv.kill().await.unwrap();
|
||||
proc.kill().await.unwrap();
|
||||
|
@ -25,7 +25,7 @@ pub async fn spawn_headless_mpv() -> Result<(Child, Mpv), MpvError> {
|
||||
.spawn()
|
||||
.expect("Failed to start mpv");
|
||||
|
||||
timeout(Duration::from_millis(500), async {
|
||||
timeout(Duration::from_millis(1000), async {
|
||||
while !&socket_path.exists() {
|
||||
sleep(Duration::from_millis(10)).await;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ async fn test_observe_event_successful() {
|
||||
assert_eq!(
|
||||
event,
|
||||
Event::PropertyChange {
|
||||
id: 1,
|
||||
id: Some(1),
|
||||
name: "volume".to_string(),
|
||||
data: Some(MpvDataType::Double(64.0))
|
||||
}
|
||||
|
@ -151,8 +151,8 @@ async fn test_get_property_simultaneous_requests() {
|
||||
tokio::time::sleep(Duration::from_millis(2)).await;
|
||||
let maybe_volume = mpv_clone_3.get_property::<f64>("nonexistent").await;
|
||||
match maybe_volume {
|
||||
Err(MpvError::MpvError(err)) => {
|
||||
assert_eq!(err, "property not found");
|
||||
Err(MpvError::MpvError { message, .. }) => {
|
||||
assert_eq!(message, "property not found");
|
||||
}
|
||||
_ => panic!("Unexpected result: {:?}", maybe_volume),
|
||||
}
|
||||
|
@ -63,12 +63,12 @@ async fn test_set_property_wrong_type() -> Result<(), MpvError> {
|
||||
let mpv = Mpv::connect_socket(server).await?;
|
||||
let maybe_volume = mpv.set_property::<bool>("volume", true).await;
|
||||
|
||||
assert_eq!(
|
||||
maybe_volume,
|
||||
Err(MpvError::MpvError(
|
||||
"unsupported format for accessing property".to_string()
|
||||
))
|
||||
);
|
||||
match maybe_volume {
|
||||
Err(MpvError::MpvError { message, .. }) => {
|
||||
assert_eq!(message, "unsupported format for accessing property");
|
||||
}
|
||||
_ => panic!("Unexpected result: {:?}", maybe_volume),
|
||||
}
|
||||
|
||||
join_handle.await.unwrap().unwrap();
|
||||
|
||||
@ -84,10 +84,12 @@ async fn test_get_property_error() -> Result<(), MpvError> {
|
||||
let mpv = Mpv::connect_socket(server).await?;
|
||||
let maybe_volume = mpv.set_property("nonexistent", true).await;
|
||||
|
||||
assert_eq!(
|
||||
maybe_volume,
|
||||
Err(MpvError::MpvError("property not found".to_string()))
|
||||
);
|
||||
match maybe_volume {
|
||||
Err(MpvError::MpvError { message, .. }) => {
|
||||
assert_eq!(message, "property not found");
|
||||
}
|
||||
_ => panic!("Unexpected result: {:?}", maybe_volume),
|
||||
}
|
||||
|
||||
join_handle.await.unwrap().unwrap();
|
||||
|
||||
@ -161,8 +163,8 @@ async fn test_set_property_simultaneous_requests() {
|
||||
tokio::time::sleep(Duration::from_millis(2)).await;
|
||||
let maybe_volume = mpv_clone_3.set_property("nonexistent", "a").await;
|
||||
match maybe_volume {
|
||||
Err(MpvError::MpvError(err)) => {
|
||||
assert_eq!(err, "property not found");
|
||||
Err(MpvError::MpvError { message, .. }) => {
|
||||
assert_eq!(message, "property not found");
|
||||
}
|
||||
_ => panic!("Unexpected result: {:?}", maybe_volume),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user