diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index 192af230c62d961efb68792671a137820998d8c8..7c769b63bc29f16b70b9fe28303e447aa6a50eb0 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -46,6 +46,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "amadeus" version = "0.1.0" @@ -125,6 +134,78 @@ dependencies = [ "libloading", ] +[[package]] +name = "async-broadcast" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b19760fa2b7301cf235360ffd6d3558b1ed4249edd16d6cca8d690cee265b95" +dependencies = [ + "event-listener", + "futures-core", + "parking_lot 0.12.1", +] + +[[package]] +name = "async-executor" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" +dependencies = [ + "async-lock", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-io" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" +dependencies = [ + "async-lock", + "autocfg", + "concurrent-queue", + "futures-lite", + "libc", + "log", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "windows-sys 0.42.0", +] + +[[package]] +name = "async-lock" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" +dependencies = [ + "event-listener", + "futures-lite", +] + +[[package]] +name = "async-recursion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b015a331cc64ebd1774ba119538573603427eaace0a1950c423ab971f903796" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-task" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" + [[package]] name = "async-trait" version = "0.1.64" @@ -181,6 +262,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" +[[package]] +name = "block-buffer" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.12.0" @@ -395,6 +485,15 @@ dependencies = [ "toml 0.7.1", ] +[[package]] +name = "concurrent-queue" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const_panic" version = "0.2.7" @@ -454,6 +553,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.3.2" @@ -535,6 +643,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "cty" version = "0.2.2" @@ -587,6 +705,17 @@ dependencies = [ "syn", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "diesel" version = "2.0.3" @@ -620,6 +749,36 @@ dependencies = [ "migrations_macros", ] +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "dispatch" version = "0.2.0" @@ -702,6 +861,27 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "enumflags2" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "errno" version = "0.2.8" @@ -752,6 +932,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "expat-sys" version = "2.1.6" @@ -777,6 +963,15 @@ dependencies = [ "threadpool", ] +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + [[package]] name = "find-crate" version = "0.6.3" @@ -937,6 +1132,21 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.26" @@ -987,6 +1197,16 @@ dependencies = [ "byteorder", ] +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "gethostname" version = "0.2.3" @@ -1210,6 +1430,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hexf-parse" version = "0.2.1" @@ -1817,6 +2043,18 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "mpris" +version = "0.1.0" +dependencies = [ + "commons", + "getset", + "hashbrown 0.13.2", + "serde", + "smallstring", + "zbus", +] + [[package]] name = "mutate_once" version = "0.1.1" @@ -1946,6 +2184,7 @@ dependencies = [ "cfg-if", "libc", "memoffset 0.6.5", + "pin-utils", ] [[package]] @@ -2088,6 +2327,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ordered-stream" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360a24bdacdb7801a1a6af8500392864791c130ebe8bd9a063158cab00040c90" +dependencies = [ + "futures-core", + "pin-project-lite", +] + [[package]] name = "os_str_bytes" version = "6.4.1" @@ -2127,6 +2376,12 @@ dependencies = [ "syn", ] +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + [[package]] name = "parking_lot" version = "0.11.2" @@ -2273,6 +2528,20 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" +dependencies = [ + "autocfg", + "cfg-if", + "libc", + "log", + "wepoll-ffi", + "windows-sys 0.42.0", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2432,6 +2701,43 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "renderdoc-sys" version = "0.7.1" @@ -2680,6 +2986,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.1" @@ -2722,6 +3039,17 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "siphasher" version = "0.3.10" @@ -2862,6 +3190,20 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -3090,9 +3432,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" version = "0.1.30" @@ -3125,6 +3479,22 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "uds_windows" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce65604324d3cce9b966701489fbd0cf318cb1f7bd9dd07ac9a4ee6fb791930d" +dependencies = [ + "tempfile", + "winapi", +] + [[package]] name = "unicode-bidi" version = "0.3.10" @@ -3199,6 +3569,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + [[package]] name = "want" version = "0.3.0" @@ -3404,6 +3780,15 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + [[package]] name = "wgpu" version = "0.14.2" @@ -3782,3 +4167,91 @@ name = "xml-rs" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "zbus" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23eaeb1859a3cd5c5f780b101dfe626bf250a5f34873c3c0226d6d9f7a4d107c" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-recursion", + "async-task", + "async-trait", + "byteorder", + "derivative", + "dirs", + "enumflags2", + "event-listener", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.25.1", + "once_cell", + "ordered-stream", + "rand", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83c1c6d669caa4773ebe8cb2ebea2a8d0c6ea27fc6c5c8916c7308cbf1db3b1" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "zbus_names" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f34f314916bd89bdb9934154627fab152f4f28acdda03e7c4c68181b214fe7e3" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zvariant" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576cc41e65c7f283e5460f5818073e68fb1f1631502b969ef228c2e03c862efb" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd4aafc0dee96ae7242a24249ce9babf21e1562822f03df650d4e68c20e41ed" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 1bab32ff0ea30992aff0fe37ffd4a9d7deee0f4c..41cd93d93214cddc52d96397a989548c93aeaae5 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -13,6 +13,7 @@ members = [ "commons", "getset", "smallstring", + "mpris", # Clients "amadeus", @@ -30,8 +31,11 @@ license = "MIT" libc = "0.2" lazy_static = "^1" thiserror = "^1" -async-trait = "^0.1" +# DBus interactions +zbus = { version = "^3" } + +# Data Structures hashbrown = { version = "^0.13", features = ["serde"] } smallvec = { version = "^1", default-features = false, features = [ "serde", @@ -41,6 +45,7 @@ smallvec = { version = "^1", default-features = false, features = [ "const_new", ] } +# Serialization & Deserialization serde_json = { version = "^1", default-features = false, features = [ "std", "preserve_order", @@ -50,7 +55,14 @@ serde = { version = "^1", default-features = false, features = [ "std", "derive", ] } +reqwest = { version = "0.11", default-features = false, features = [ + "rustls-tls", + "rustls-tls-native-roots", + "json", +] } +# Async stuff +async-trait = "^0.1" tokio = { version = "1", features = [ "rt", "rt-multi-thread", @@ -61,12 +73,7 @@ tokio = { version = "1", features = [ "io-util", ] } -reqwest = { version = "0.11", default-features = false, features = [ - "rustls-tls", - "rustls-tls-native-roots", - "json", -] } - +# Arguments clap = { version = "^4", default-features = false, features = [ "usage", "help", @@ -77,6 +84,7 @@ clap = { version = "^4", default-features = false, features = [ "derive", ] } +# GUI iced = { version = "0.7", features = ["image", "tokio"] } [profile.release] diff --git a/src/rust/mpris/Cargo.toml b/src/rust/mpris/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..9701120a9c15b54cdeef3bc06948e3b84e398e90 --- /dev/null +++ b/src/rust/mpris/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "mpris" +version.workspace = true +edition.workspace = true +authors.workspace = true +license.workspace = true + +[lib] +doctest = false + +[dependencies] +hashbrown.workspace = true +serde.workspace = true +zbus.workspace = true + +smallstring = { path = "../smallstring" } +commons = { path = "../commons" } +getset = { path = "../getset" } diff --git a/src/rust/mpris/src/lib.rs b/src/rust/mpris/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..d28c42369f2242ca0e4243259e9cf249c369b5d6 --- /dev/null +++ b/src/rust/mpris/src/lib.rs @@ -0,0 +1,2 @@ +pub mod traits; +pub mod types; diff --git a/src/rust/mpris/src/traits.rs b/src/rust/mpris/src/traits.rs new file mode 100644 index 0000000000000000000000000000000000000000..e964c95393727d50d820e5dcb0ee3124d04110ef --- /dev/null +++ b/src/rust/mpris/src/traits.rs @@ -0,0 +1,166 @@ +//! # DBus interface proxies for: `org.mpris.MediaPlayer2`, `org.mpris.MediaPlayer2.Player` +//! +//! This code was generated by `zbus-xmlgen` `3.1.0` from DBus introspection data. +//! Source: `mpris.xml`. +//! +//! You may prefer to adapt it, instead of using it verbatim. +//! +//! More information can be found in the +//! [Writing a client proxy](https://dbus.pages.freedesktop.org/zbus/client.html) +//! section of the zbus documentation. + +use crate::types::*; +use zbus::dbus_proxy; + +#[dbus_proxy(interface = "org.mpris.MediaPlayer2", assume_defaults = true)] +trait MediaPlayer2 { + /// Quit method + fn quit(&self) -> zbus::Result<()>; + + /// Raise method + fn raise(&self) -> zbus::Result<()>; + + /// CanQuit property + #[dbus_proxy(property)] + fn can_quit(&self) -> zbus::Result<bool>; + + /// CanRaise property + #[dbus_proxy(property)] + fn can_raise(&self) -> zbus::Result<bool>; + + /// CanSetFullscreen property + #[dbus_proxy(property)] + fn can_set_fullscreen(&self) -> zbus::Result<bool>; + + /// DesktopEntry property + #[dbus_proxy(property)] + fn desktop_entry(&self) -> zbus::Result<String>; + + /// Fullscreen property + #[dbus_proxy(property)] + fn fullscreen(&self) -> zbus::Result<bool>; + fn set_fullscreen(&self, value: bool) -> zbus::Result<()>; + + /// HasTrackList property + #[dbus_proxy(property)] + fn has_track_list(&self) -> zbus::Result<bool>; + + /// Identity property + #[dbus_proxy(property)] + fn identity(&self) -> zbus::Result<String>; + + /// SupportedMimeTypes property + #[dbus_proxy(property)] + fn supported_mime_types(&self) -> zbus::Result<Vec<String>>; + + /// SupportedUriSchemes property. It should be `id://` and `file://` for + /// lektord. Here we support `file://` for only files in the database to + /// enable the user to search the kara folder and drop the files to play + /// them imediatly. + #[dbus_proxy(property)] + fn supported_uri_schemes(&self) -> zbus::Result<Vec<String>>; +} + +#[dbus_proxy(interface = "org.mpris.MediaPlayer2.Player", assume_defaults = true)] +trait Player { + /// Next method + fn next(&self) -> zbus::Result<()>; + + /// OpenUri method + fn open_uri(&self, id_uri: &str) -> zbus::Result<()>; + + /// Pause method + fn pause(&self) -> zbus::Result<()>; + + /// Play method + fn play(&self) -> zbus::Result<()>; + + /// PlayPause method + fn play_pause(&self) -> zbus::Result<()>; + + /// Previous method + fn previous(&self) -> zbus::Result<()>; + + /// Seek method + fn seek(&self, time: TimeMicroSec) -> zbus::Result<()>; + + /// SetPosition method + fn set_position( + &self, + track_id: &MediaPlayerObjectPath, + time: TimeMicroSec, + ) -> zbus::Result<()>; + + /// Stop method + fn stop(&self) -> zbus::Result<()>; + + /// CanControl property + #[dbus_proxy(property)] + fn can_control(&self) -> zbus::Result<bool>; + + /// CanPause property + #[dbus_proxy(property)] + fn can_pause(&self) -> zbus::Result<bool>; + + /// CanPlay property + #[dbus_proxy(property)] + fn can_play(&self) -> zbus::Result<bool>; + + /// CanSeek property + #[dbus_proxy(property)] + fn can_seek(&self) -> zbus::Result<bool>; + + /// LoopStatus property + #[dbus_proxy(property)] + fn loop_status(&self) -> zbus::Result<MediaPlayerObjectPath>; + fn set_loop_status(&self, value: &MediaPlayerObjectPath) -> zbus::Result<()>; + + /// MaximumRate property. We will only set it to `1.0` here... + #[dbus_proxy(property)] + fn maximum_rate(&self) -> zbus::Result<f64> { + Ok(1.0) + } + fn set_maximum_rate(&self, _: f64) -> zbus::Result<()> { + Ok(()) + } + + /// Metadata property. If there is a current kara playing, there must be at + /// least a `mpris:trackid` value of type `o` which is the object path of + /// the current kara id. + #[dbus_proxy(property)] + fn metadata( + &self, + ) -> zbus::Result<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>; + + /// MinimumRate property. We will only set it to `1.0` here... + #[dbus_proxy(property)] + fn minimum_rate(&self) -> zbus::Result<f64> { + Ok(1.0) + } + fn set_minimum_rate(&self, _: f64) -> zbus::Result<()> { + Ok(()) + } + + /// PlaybackStatus property + #[dbus_proxy(property)] + fn playback_status(&self) -> zbus::Result<MediaPlayerPlaybackStatus>; + + /// Position property + #[dbus_proxy(property)] + fn position(&self) -> zbus::Result<TimeMicroSec>; + + /// Rate property + #[dbus_proxy(property)] + fn rate(&self) -> zbus::Result<f64>; + fn set_rate(&self, value: f64) -> zbus::Result<()>; + + /// Shuffle property + #[dbus_proxy(property)] + fn shuffle(&self) -> zbus::Result<bool>; + fn set_shuffle(&self, value: bool) -> zbus::Result<()>; + + /// Volume property + #[dbus_proxy(property)] + fn volume(&self) -> zbus::Result<f64>; + fn set_volume(&self, value: f64) -> zbus::Result<()>; +} diff --git a/src/rust/mpris/src/types.rs b/src/rust/mpris/src/types.rs new file mode 100644 index 0000000000000000000000000000000000000000..9d0067e44468427f5d594b923c9c6fae0fb1b6db --- /dev/null +++ b/src/rust/mpris/src/types.rs @@ -0,0 +1,113 @@ +use serde::{Deserialize, Serialize}; +use zbus::zvariant::{ + ObjectPath as ZObjectPath, OwnedValue as ZOwnedValue, Signature as ZSignature, Type as ZType, +}; + +/// The loop status. +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +pub enum MediaPlayerLoopStatus { + None, + Track, + Playlist, +} + +/// The playback status. +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +pub enum MediaPlayerPlaybackStatus { + Playing, + Paused, + Stopped, +} + +/// Force the time to be in µs. +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +#[serde(transparent)] +pub struct TimeMicroSec(i64); + +/// A valid path must be prefiexed by `/baka/lektor/`. After that we have the +/// variant name in lower case, then a `/`, then the ascii only value. For +/// example we can have: +/// - `/baka/lektor/id/42` +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default)] +pub enum MediaPlayerObjectPath { + /// Not an object, or nothing. + #[default] + None, + + /// An id. + Id(i64), +} + +// Implementations + +impl From<i64> for TimeMicroSec { + fn from(value: i64) -> Self { + Self(value) + } +} + +impl From<ZOwnedValue> for TimeMicroSec { + fn from(value: ZOwnedValue) -> Self { + let value: i64 = value.try_into().unwrap_or_default(); + Self(value) + } +} + +impl From<ZOwnedValue> for MediaPlayerLoopStatus { + fn from(value: ZOwnedValue) -> Self { + let value: String = value.try_into().unwrap_or_default(); + match &value[..] { + "None" => Self::None, + "Track" => Self::Track, + "Playlist" => Self::Playlist, + _ => Self::None, + } + } +} + +impl From<ZOwnedValue> for MediaPlayerPlaybackStatus { + fn from(value: ZOwnedValue) -> Self { + let value: String = value.try_into().unwrap_or_default(); + match &value[..] { + "Paused" => Self::Paused, + "Playing" => Self::Playing, + "Stopped" => Self::Stopped, + _ => Self::Stopped, + } + } +} + +impl<'a> From<ZOwnedValue> for MediaPlayerObjectPath { + fn from(value: ZOwnedValue) -> Self { + let value: ZObjectPath = value.try_into().unwrap_or_default(); + let value = value.trim_start_matches('/'); + match value.split('/').collect::<Vec<_>>()[..] { + ["baka", "lektor", "id", id] => id.parse::<i64>().map(Self::Id).unwrap_or_default(), + _ => Default::default(), + } + } +} + +impl ZType for MediaPlayerObjectPath { + fn signature() -> ZSignature<'static> { + ZSignature::try_from("o").expect("invalid signature") + } +} + +impl ZType for MediaPlayerLoopStatus { + fn signature() -> ZSignature<'static> { + ZSignature::try_from("s").expect("invalid signature") + } +} + +impl ZType for MediaPlayerPlaybackStatus { + fn signature() -> ZSignature<'static> { + ZSignature::try_from("s").expect("invalid signature") + } +} + +impl ZType for TimeMicroSec { + fn signature() -> ZSignature<'static> { + ZSignature::try_from("x").expect("invalid signature") + } +}