feat: add mpris2-zbus for org.mpris.MediaPlayer2
This commit is contained in:
parent
4d8815361d
commit
945f80f036
21 changed files with 2203 additions and 0 deletions
53
mpris2/src/playlists/id.rs
Normal file
53
mpris2/src/playlists/id.rs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{
|
||||
cmp::{Ord, Ordering, PartialOrd},
|
||||
fmt::{self, Display},
|
||||
ops::Deref,
|
||||
};
|
||||
use zvariant::{ObjectPath, OwnedObjectPath, Type, Value};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Type, Serialize, Deserialize, Value)]
|
||||
pub struct PlaylistId(OwnedObjectPath);
|
||||
|
||||
impl PlaylistId {
|
||||
pub fn into_inner(self) -> OwnedObjectPath {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn into_static_path(self) -> ObjectPath<'static> {
|
||||
self.0.into_inner().into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for PlaylistId {
|
||||
type Target = OwnedObjectPath;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> AsRef<ObjectPath<'a>> for PlaylistId {
|
||||
fn as_ref(&self) -> &ObjectPath<'a> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for PlaylistId {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.0.as_str().partial_cmp(other.0.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for PlaylistId {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.0.as_str().cmp(other.0.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PlaylistId {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", self.0.as_str())
|
||||
}
|
||||
}
|
||||
120
mpris2/src/playlists/ordering.rs
Normal file
120
mpris2/src/playlists/ordering.rs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
use crate::error::{Error, Result};
|
||||
use serde::{
|
||||
de::{self, Deserialize, Visitor},
|
||||
ser::{Serialize, Serializer},
|
||||
};
|
||||
use std::{
|
||||
fmt::{self, Display},
|
||||
str::FromStr,
|
||||
};
|
||||
use zvariant::{OwnedValue, Signature, Type, Value};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||
pub enum PlaylistOrdering {
|
||||
/// Alphabetical ordering by name, ascending.
|
||||
Alphabetical,
|
||||
/// Ordering by creation date, oldest first.
|
||||
CreationDate,
|
||||
/// Ordering by last modified date, oldest first.
|
||||
ModifiedDate,
|
||||
/// Ordering by date of last playback, oldest first.
|
||||
LastPlayDate,
|
||||
/// A user-defined ordering.
|
||||
UserDefined,
|
||||
}
|
||||
|
||||
impl Type for PlaylistOrdering {
|
||||
fn signature() -> Signature<'static> {
|
||||
String::signature()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> TryFrom<Value<'a>> for PlaylistOrdering {
|
||||
type Error = Error;
|
||||
|
||||
fn try_from(value: Value<'a>) -> Result<Self> {
|
||||
match value {
|
||||
Value::Str(value) => Self::from_str(&value),
|
||||
_ => Err(Error::IncorrectValue {
|
||||
wanted: "Str",
|
||||
actual: OwnedValue::from(value),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<PlaylistOrdering> for Value<'a> {
|
||||
fn from(ordering: PlaylistOrdering) -> Self {
|
||||
Value::Str(ordering.to_string().into())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for PlaylistOrdering {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self> {
|
||||
match s.to_lowercase().trim() {
|
||||
"alphabetical" => Ok(Self::Alphabetical),
|
||||
"created" => Ok(Self::CreationDate),
|
||||
"modified" => Ok(Self::ModifiedDate),
|
||||
"played" => Ok(Self::LastPlayDate),
|
||||
"user" => Ok(Self::UserDefined),
|
||||
_ => Err(Error::InvalidEnum {
|
||||
got: s.to_string(),
|
||||
expected: &["Alphabetical", "Created", "Modified", "Played", "User"],
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PlaylistOrdering {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Alphabetical => "Alphabetical",
|
||||
Self::CreationDate => "Created",
|
||||
Self::ModifiedDate => "Modified",
|
||||
Self::LastPlayDate => "Played",
|
||||
Self::UserDefined => "User",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for PlaylistOrdering {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.to_string().as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for PlaylistOrdering {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_str(PlaylistOrderingVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaylistOrderingVisitor;
|
||||
|
||||
impl Visitor<'_> for PlaylistOrderingVisitor {
|
||||
type Value = PlaylistOrdering;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, s: &str) -> std::result::Result<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
PlaylistOrdering::from_str(s).map_err(de::Error::custom)
|
||||
}
|
||||
}
|
||||
21
mpris2/src/playlists/playlist.rs
Normal file
21
mpris2/src/playlists/playlist.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
use super::id::PlaylistId;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zbus::zvariant::{Type, Value};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Type, Value, Serialize, Deserialize)]
|
||||
pub struct Playlist((PlaylistId, String, String));
|
||||
|
||||
impl Playlist {
|
||||
pub fn id(&self) -> &PlaylistId {
|
||||
&self.0 .0
|
||||
}
|
||||
|
||||
pub fn name(&self) -> &str {
|
||||
&self.0 .1
|
||||
}
|
||||
|
||||
pub fn icon(&self) -> &str {
|
||||
&self.0 .2
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue