From 2d87d4aff65e11a6bb06d6a1674b057dfadaa7e2 Mon Sep 17 00:00:00 2001 From: "NGnius (Graham)" Date: Sun, 29 May 2022 11:56:08 -0400 Subject: [PATCH] Use URIs in filename instead of assuming everything is a filepath --- Cargo.lock | 338 ++++++++++--------- mps-interpreter/src/music/tag.rs | 2 +- mps-interpreter/src/processing/filesystem.rs | 2 +- mps-player/Cargo.toml | 1 + mps-player/src/controller.rs | 51 +-- mps-player/src/errors.rs | 60 ++++ mps-player/src/lib.rs | 3 +- mps-player/src/os_controls.rs | 3 +- mps-player/src/player.rs | 96 +++--- mps-player/src/player_wrapper.rs | 4 +- mps-player/src/uri.rs | 29 ++ src/main.rs | 4 +- src/repl.rs | 4 +- 13 files changed, 356 insertions(+), 241 deletions(-) create mode 100644 mps-player/src/uri.rs diff --git a/Cargo.lock b/Cargo.lock index b372674..a0a4304 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,7 @@ version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ - "memchr 2.4.1", + "memchr 2.5.0", ] [[package]] @@ -70,9 +70,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.56" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4361135be9122e0870de935d7c439aef945b9f9ddd4199a553b5270b49c82a27" +checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" [[package]] name = "arrayvec" @@ -99,9 +99,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bindgen" -version = "0.56.0" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2da379dbebc0b76ef63ca68d8fc6e71c0f13e59432e0987e508c1820e6ab5239" +checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8" dependencies = [ "bitflags", "cexpr", @@ -111,7 +111,7 @@ dependencies = [ "peeking_take_while", "proc-macro2", "quote", - "regex 1.5.5", + "regex 1.5.6", "rustc-hash", "shlex", ] @@ -207,7 +207,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ "lazy_static 1.4.0", - "memchr 2.4.1", + "memchr 2.5.0", "regex-automata", "serde", ] @@ -232,9 +232,9 @@ checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" [[package]] name = "bytemuck" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e851ca7c24871e7336801608a4797d7376545b6928a10d32d75685687141ead" +checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" [[package]] name = "byteorder" @@ -295,11 +295,11 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cexpr" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "nom 5.1.2", + "nom", ] [[package]] @@ -320,9 +320,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.3.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cc00842eed744b858222c4c9faf7243aafc6d33f92f96935263ef4d8a41ce21" +checksum = "bf6b561dcf059c85bbe388e0a7b0a1469acb3934cc0cfa148613a830629e3049" dependencies = [ "glob", "libc", @@ -346,16 +346,16 @@ dependencies = [ [[package]] name = "clap" -version = "3.1.6" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c93436c21e4698bacadf42917db28b23017027a4deccb35dbe47a7e7840123" +checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" dependencies = [ "atty", "bitflags", "clap_derive", + "clap_lex", "indexmap", "lazy_static 1.4.0", - "os_str_bytes", "strsim 0.10.0", "termcolor", "textwrap 0.15.0", @@ -363,9 +363,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "3.1.4" +version = "3.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16" +checksum = "25320346e922cffe59c0bbc5410c8d8784509efb321488971081313cb1e1a33c" dependencies = [ "heck 0.4.0", "proc-macro-error", @@ -374,6 +374,15 @@ dependencies = [ "syn", ] +[[package]] +name = "clap_lex" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "claxon" version = "0.4.3" @@ -382,12 +391,12 @@ checksum = "4bfbf56724aa9eca8afa4fcfadeb479e722935bb2a0900c2d37e0cc477af0688" [[package]] name = "combine" -version = "4.6.3" +version = "4.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b727aacc797f9fc28e355d21f34709ac4fc9adecfe470ad07b8f4464f53062" +checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" dependencies = [ "bytes", - "memchr 2.4.1", + "memchr 2.5.0", ] [[package]] @@ -399,7 +408,7 @@ dependencies = [ "encode_unicode", "libc", "once_cell", - "regex 1.5.5", + "regex 1.5.6", "terminal_size", "unicode-width", "winapi 0.3.9", @@ -423,9 +432,9 @@ dependencies = [ [[package]] name = "coreaudio-sys" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca4679a59dbd8c15f064c012dfe8c1163b9453224238b59bb9328c142b8b248b" +checksum = "3dff444d80630d7073077d38d40b4501fd518bd2b922c2a55edcc8b0f7be57e6" dependencies = [ "bindgen", ] @@ -481,7 +490,7 @@ dependencies = [ "oorandom", "plotters", "rayon", - "regex 1.5.5", + "regex 1.5.6", "serde", "serde_cbor", "serde_derive", @@ -516,9 +525,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdbfe11fe19ff083c48923cf179540e8cd0535903dc35e178a1fdeeb59aef51f" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" dependencies = [ "cfg-if", "crossbeam-utils", @@ -588,14 +597,14 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "memchr 2.4.1", + "memchr 2.5.0", ] [[package]] name = "darling" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -603,9 +612,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", @@ -617,9 +626,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.1" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", @@ -675,9 +684,9 @@ dependencies = [ [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", @@ -709,9 +718,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] @@ -725,7 +734,7 @@ dependencies = [ "atty", "humantime", "log", - "regex 1.5.5", + "regex 1.5.6", "termcolor", ] @@ -773,9 +782,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" dependencies = [ "cfg-if", "crc32fast", @@ -783,6 +792,15 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fluent-uri" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80caca0b85a39e8e4139c36441543e698b204279ae8065b3af413c9bf8b33146" +dependencies = [ + "bitflags", +] + [[package]] name = "fnv" version = "1.0.7" @@ -827,9 +845,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39cd93900197114fa1fcb7ae84ca742095eed9442088988ae74fa744e930e77" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if", "libc", @@ -910,9 +928,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "indexmap" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" dependencies = [ "autocfg", "hashbrown", @@ -944,9 +962,9 @@ checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" [[package]] name = "jni" @@ -979,9 +997,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" dependencies = [ "wasm-bindgen", ] @@ -1027,9 +1045,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.120" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad5c14e80759d0939d013e6ca49930e59fc53dd8e5009132f76240c179380c09" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" [[package]] name = "libdbus-sys" @@ -1063,18 +1081,19 @@ dependencies = [ [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] @@ -1085,7 +1104,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50fe05791a7f418b59d6cddebdc293d77c9c1f652adbff855c071d4507cd883b" dependencies = [ - "nom 7.1.1", + "nom", ] [[package]] @@ -1123,9 +1142,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "memoffset" @@ -1180,12 +1199,11 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.4.4" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" dependencies = [ "adler", - "autocfg", ] [[package]] @@ -1210,7 +1228,7 @@ dependencies = [ name = "mps" version = "0.8.0" dependencies = [ - "clap 3.1.6", + "clap 3.1.18", "console", "mps-interpreter", "mps-player", @@ -1225,7 +1243,7 @@ dependencies = [ "dirs", "mpd", "rand", - "regex 1.5.5", + "regex 1.5.6", "rusqlite", "shellexpand", "symphonia 0.5.0", @@ -1235,7 +1253,7 @@ dependencies = [ name = "mps-m3u8" version = "0.8.0" dependencies = [ - "clap 3.1.6", + "clap 3.1.18", "m3u8-rs", "mps-interpreter", ] @@ -1244,6 +1262,7 @@ dependencies = [ name = "mps-player" version = "0.8.0" dependencies = [ + "fluent-uri", "m3u8-rs", "mpris-player", "mps-interpreter", @@ -1257,7 +1276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dec23e6762830658d2b3d385a75aa212af2f67a4586d4442907144f3bb6a1ca8" dependencies = [ "matrixmultiply", - "num-complex 0.4.0", + "num-complex 0.4.1", "num-integer", "num-traits", "rawpointer", @@ -1272,7 +1291,7 @@ checksum = "f85776816e34becd8bd9540818d7dc77bf28307f3b3dcc51cc82403c6931680c" dependencies = [ "byteorder", "ndarray", - "num-complex 0.4.0", + "num-complex 0.4.1", "num-traits", "py_literal", "zip", @@ -1308,15 +1327,15 @@ dependencies = [ [[package]] name = "ndk-context" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e3c5cc68637e21fe8f077f6a1c9e0b9ca495bb74895226b476310f613325884" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" [[package]] name = "ndk-glue" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ffb7443daba48349d545028777ca98853b018b4c16624aa01223bc29e078da" +checksum = "0d0c4a7b83860226e6b4183edac21851f05d5a51756e97a1144b7f5a6b63e65f" dependencies = [ "lazy_static 1.4.0", "libc", @@ -1371,23 +1390,13 @@ dependencies = [ "num-traits", ] -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "memchr 2.4.1", - "version_check", -] - [[package]] name = "nom" version = "7.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" dependencies = [ - "memchr 2.4.1", + "memchr 2.5.0", "minimal-lexical", ] @@ -1424,9 +1433,9 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" +checksum = "97fbc387afefefd5e9e39493299f3069e14a140dd34dc19b4c1c1a8fddb6a790" dependencies = [ "num-traits", ] @@ -1444,9 +1453,9 @@ dependencies = [ [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ "autocfg", "num-traits", @@ -1454,9 +1463,9 @@ dependencies = [ [[package]] name = "num-iter" -version = "0.1.42" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" dependencies = [ "autocfg", "num-integer", @@ -1465,9 +1474,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -1505,13 +1514,13 @@ dependencies = [ [[package]] name = "oboe" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2463c8f2e19b4e0d0710a21f8e4011501ff28db1c95d7a5482a553b2100502d2" +checksum = "27f63c358b4fa0fbcfefd7c8be5cfc39c08ce2389f5325687e7762a48d30a5c1" dependencies = [ "jni", "ndk", - "ndk-glue", + "ndk-context", "num-derive", "num-traits", "oboe-sys", @@ -1537,9 +1546,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" +checksum = "7b10983b38c53aebdf33f542c6275b0f58a238129d00c4ae0e6fb59738d783ca" [[package]] name = "oorandom" @@ -1561,12 +1570,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "os_str_bytes" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" -dependencies = [ - "memchr 2.4.1", -] +checksum = "029d8d0b2f198229de29dca79676f2738ff952edf3fde542eb8bf94d8c21b435" [[package]] name = "parking_lot" @@ -1644,9 +1650,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" [[package]] name = "plotters" @@ -1727,11 +1733,11 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.36" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" +checksum = "c54b25569025b7fc9651de43004ae593a75ad88543b17178aa5e1b9c4f15f56f" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] @@ -1741,7 +1747,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "102df7a3d46db9d3891f178dcc826dc270a6746277a9ae6436f8d29fd490a8e1" dependencies = [ "num-bigint", - "num-complex 0.4.0", + "num-complex 0.4.1", "num-traits", "pest", "pest_derive", @@ -1749,9 +1755,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.15" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" dependencies = [ "proc-macro2", ] @@ -1794,9 +1800,9 @@ checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" [[package]] name = "rayon" -version = "1.5.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d" dependencies = [ "autocfg", "crossbeam-deque", @@ -1806,34 +1812,34 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f" dependencies = [ "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static 1.4.0", "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.2.11" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c" +checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] @@ -1851,13 +1857,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.5.5" +version = "1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +checksum = "d83f127d94bdbcda4c8cc2e50f6f84f4b611f69c902699ca385a39c3a75f9ff1" dependencies = [ "aho-corasick 0.7.18", - "memchr 2.4.1", - "regex-syntax 0.6.25", + "memchr 2.5.0", + "regex-syntax 0.6.26", ] [[package]] @@ -1874,9 +1880,9 @@ checksum = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957" [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" +checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64" [[package]] name = "ripemd160" @@ -1914,7 +1920,7 @@ dependencies = [ "fallible-streaming-iterator", "hashlink", "libsqlite3-sys", - "memchr 2.4.1", + "memchr 2.5.0", "smallvec", ] @@ -1955,9 +1961,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" [[package]] name = "same-file" @@ -1976,15 +1982,15 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "semver" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" +checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd" [[package]] name = "serde" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1" dependencies = [ "serde_derive", ] @@ -2001,9 +2007,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.136" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be" dependencies = [ "proc-macro2", "quote", @@ -2012,11 +2018,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" dependencies = [ - "itoa 1.0.1", + "itoa 1.0.2", "ryu", "serde", ] @@ -2044,9 +2050,9 @@ dependencies = [ [[package]] name = "shlex" -version = "0.1.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "slice-deque" @@ -2427,13 +2433,13 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.88" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd69e719f31e88618baa1eaa6ee2de5c9a1c004f1e9ecdb58e8352a13f20a01" +checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] @@ -2472,18 +2478,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "thiserror" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" dependencies = [ "proc-macro2", "quote", @@ -2531,9 +2537,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ "tinyvec_macros", ] @@ -2546,9 +2552,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "toml" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" dependencies = [ "serde", ] @@ -2584,6 +2590,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "unicode-ident" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee" + [[package]] name = "unicode-segmentation" version = "1.9.0" @@ -2596,12 +2608,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - [[package]] name = "utf8-ranges" version = "0.1.3" @@ -2645,9 +2651,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -2655,9 +2661,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" dependencies = [ "bumpalo", "lazy_static 1.4.0", @@ -2670,9 +2676,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2680,9 +2686,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" dependencies = [ "proc-macro2", "quote", @@ -2693,15 +2699,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.79" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" [[package]] name = "web-sys" -version = "0.3.56" +version = "0.3.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" +checksum = "7b17e741662c70c8bd24ac5c5b18de314a2c26c32bf8346ee1e6f53de919c283" dependencies = [ "js-sys", "wasm-bindgen", diff --git a/mps-interpreter/src/music/tag.rs b/mps-interpreter/src/music/tag.rs index c3dc251..f471471 100644 --- a/mps-interpreter/src/music/tag.rs +++ b/mps-interpreter/src/music/tag.rs @@ -114,7 +114,7 @@ impl Tags { title: self.track_title(), artist: artist_id, album: album_id, - filename: self.filename.to_str().unwrap_or("").into(), + filename: format!("file://{}", self.filename.to_str().unwrap_or("")), metadata: meta_id, genre: genre_id, } diff --git a/mps-interpreter/src/processing/filesystem.rs b/mps-interpreter/src/processing/filesystem.rs index b63b019..ffaeea4 100644 --- a/mps-interpreter/src/processing/filesystem.rs +++ b/mps-interpreter/src/processing/filesystem.rs @@ -234,7 +234,7 @@ impl FileIter { } } } - item.set_field("filename", path_str.to_string().into()); + item.set_field("filename", format!("file://{}", path_str).into()); } fn only_once(&mut self) -> Result { diff --git a/mps-player/Cargo.toml b/mps-player/Cargo.toml index ac54c6b..58a619b 100644 --- a/mps-player/Cargo.toml +++ b/mps-player/Cargo.toml @@ -8,6 +8,7 @@ readme = "README.md" [dependencies] rodio = { version = "^0.15", features = ["symphonia-all"]} m3u8-rs = { version = "^3.0.0" } +fluent-uri = { version = "^0.1" } # local mps-interpreter = { path = "../mps-interpreter", version = "0.8.0" } diff --git a/mps-player/src/controller.rs b/mps-player/src/controller.rs index 49e7b2b..1fe2a0d 100644 --- a/mps-player/src/controller.rs +++ b/mps-player/src/controller.rs @@ -7,6 +7,7 @@ use super::os_controls::SystemControlWrapper; use super::player_wrapper::{ControlAction, MpsPlayerServer, PlayerAction}; use super::MpsPlayer; use super::PlaybackError; +use super::PlayerError; /// A controller for a MpsPlayer running on another thread. /// This receives and sends events like media buttons and script errors for the MpsPlayer. @@ -74,14 +75,14 @@ impl MpsController { } } - fn send_confirm(&self, to_send: ControlAction) -> Result<(), PlaybackError> { + fn send_confirm(&self, to_send: ControlAction) -> Result<(), PlayerError> { self.control .send(to_send.clone()) - .map_err(PlaybackError::from_err)?; - let mut response = self.event.recv().map_err(PlaybackError::from_err)?; + .map_err(PlayerError::from_err_playback)?; + let mut response = self.event.recv().map_err(PlayerError::from_err_playback)?; while !response.is_acknowledgement() { self.handle_event(response)?; - response = self.event.recv().map_err(PlaybackError::from_err)?; + response = self.event.recv().map_err(PlayerError::from_err_playback)?; } if let PlayerAction::Acknowledge(action) = response { if action == to_send { @@ -90,16 +91,16 @@ impl MpsController { Err(PlaybackError { msg: "Incorrect acknowledgement received for MpsController control action" .into(), - }) + }.into()) } } else { Err(PlaybackError { msg: "Invalid acknowledgement received for MpsController control action".into(), - }) + }.into()) } } - fn handle_event(&self, event: PlayerAction) -> Result<(), PlaybackError> { + fn handle_event(&self, event: PlayerAction) -> Result<(), PlayerError> { match event { PlayerAction::Acknowledge(_) => Ok(()), PlayerAction::Exception(e) => Err(e), @@ -109,51 +110,51 @@ impl MpsController { } } - pub fn next(&self) -> Result<(), PlaybackError> { + pub fn next(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Next { ack: true }) } - pub fn previous(&self) -> Result<(), PlaybackError> { + pub fn previous(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Previous { ack: true }) } - pub fn play(&self) -> Result<(), PlaybackError> { + pub fn play(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Play { ack: true }) } - pub fn pause(&self) -> Result<(), PlaybackError> { + pub fn pause(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Pause { ack: true }) } - pub fn stop(&self) -> Result<(), PlaybackError> { + pub fn stop(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Stop { ack: true }) } - pub fn enqueue(&self, count: usize) -> Result<(), PlaybackError> { + pub fn enqueue(&self, count: usize) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Enqueue { amount: count, ack: true, }) } - pub fn ping(&self) -> Result<(), PlaybackError> { + pub fn ping(&self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::NoOp { ack: true }) } - pub fn exit(self) -> Result<(), PlaybackError> { + pub fn exit(self) -> Result<(), PlayerError> { self.send_confirm(ControlAction::Exit { ack: true })?; self.sys_ctrl.exit(); match self.handle.join() { Ok(x) => Ok(x), Err(_) => Err(PlaybackError { msg: "MpsPlayerServer did not exit correctly".into(), - }), + }.into()), } } - pub fn wait_for_done(&self) -> Result<(), PlaybackError> { + pub fn wait_for_done(&self) -> Result<(), PlayerError> { loop { - let msg = self.event.recv().map_err(PlaybackError::from_err)?; + let msg = self.event.recv().map_err(PlayerError::from_err_playback)?; if let PlayerAction::End = msg { break; } else { @@ -163,15 +164,15 @@ impl MpsController { Ok(()) } - pub fn wait_for_empty(&self) -> Result<(), PlaybackError> { + pub fn wait_for_empty(&self) -> Result<(), PlayerError> { for msg in self.event.try_iter() { self.handle_event(msg)?; } self.control .send(ControlAction::CheckEmpty { ack: true }) - .map_err(PlaybackError::from_err)?; + .map_err(PlayerError::from_err_playback)?; loop { - let msg = self.event.recv().map_err(PlaybackError::from_err)?; + let msg = self.event.recv().map_err(PlayerError::from_err_playback)?; if let PlayerAction::Empty = msg { break; } else { @@ -183,7 +184,7 @@ impl MpsController { /// Check for any errors in the event queue. /// This is non-blocking, so it only handles events sent since the last time events were handled. - pub fn check(&self) -> Vec { + pub fn check(&self) -> Vec { let mut result = Vec::new(); for msg in self.event.try_iter() { if let Err(e) = self.handle_event(msg) { @@ -194,13 +195,13 @@ impl MpsController { } /// Like check(), but it also waits for an acknowledgement to ensure it gets the latest events. - pub fn check_ack(&self) -> Vec { + pub fn check_ack(&self) -> Vec { let mut result = self.check(); // clear existing messages first let to_send = ControlAction::NoOp { ack: true }; if let Err(e) = self .control .send(to_send.clone()) - .map_err(PlaybackError::from_err) + .map_err(PlayerError::from_err_playback) { result.push(e); } @@ -212,7 +213,7 @@ impl MpsController { result.push(PlaybackError { msg: "Incorrect acknowledgement received for MpsController control action" .into(), - }); + }.into()); } } else if let Err(e) = self.handle_event(msg) { result.push(e); diff --git a/mps-player/src/errors.rs b/mps-player/src/errors.rs index bcc941c..920facb 100644 --- a/mps-player/src/errors.rs +++ b/mps-player/src/errors.rs @@ -1,4 +1,30 @@ use std::fmt::{Debug, Display, Error, Formatter}; +use std::convert::Into; + +#[derive(Debug, Clone)] +pub enum PlayerError { + Playback(PlaybackError), + Uri(UriError), +} + +impl PlayerError { + pub(crate) fn from_err_playback(err: E) -> Self { + Self::Playback(PlaybackError::from_err(err)) + } + + /*pub(crate) fn from_err_uri(err: E) -> Self { + Self::Uri(UriError::from_err(err)) + }*/ +} + +impl Display for PlayerError { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + match self { + Self::Playback(p) => (p as &dyn Display).fmt(f), + Self::Uri(u) => (u as &dyn Display).fmt(f), + } + } +} #[derive(Debug, Clone)] pub struct PlaybackError { @@ -22,3 +48,37 @@ impl Display for PlaybackError { write!(f, "PlaybackError: {}", &self.msg) } } + +impl Into for PlaybackError { + fn into(self) -> PlayerError { + PlayerError::Playback(self) + } +} + +#[derive(Debug, Clone)] +pub enum UriError { + Unsupported(String), + Message(String) +} + +impl UriError { + pub fn from_err(err: E) -> Self { + Self::Message(format!("{}", err)) + } +} + +impl Display for UriError { + fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { + write!(f, "UriError: ")?; + match self { + Self::Unsupported(scheme) => write!(f, "Unsupported URI `{}//`", scheme), + Self::Message(msg) => write!(f, "{}", msg) + } + } +} + +impl Into for UriError { + fn into(self) -> PlayerError { + PlayerError::Uri(self) + } +} diff --git a/mps-player/src/lib.rs b/mps-player/src/lib.rs index d3ea138..2e0b18f 100644 --- a/mps-player/src/lib.rs +++ b/mps-player/src/lib.rs @@ -8,10 +8,11 @@ mod errors; pub(crate) mod os_controls; mod player; pub(crate) mod player_wrapper; +pub(crate) mod uri; //mod utility; pub use controller::MpsController; -pub use errors::PlaybackError; +pub use errors::{PlaybackError, UriError, PlayerError}; pub use player::MpsPlayer; //pub use utility::{play_script}; diff --git a/mps-player/src/os_controls.rs b/mps-player/src/os_controls.rs index ae6e737..7d15150 100644 --- a/mps-player/src/os_controls.rs +++ b/mps-player/src/os_controls.rs @@ -181,8 +181,7 @@ impl SystemControlWrapper { //println!("Got enqueued item {}", &item.title); let file_uri = item .field("filename") - .and_then(|x| x.to_owned().to_str()) - .map(|x| format!("file://{}", x)); + .and_then(|x| x.to_owned().to_str()); dbus_ctrl .send(DbusControl::SetMetadata(Metadata { length: None, diff --git a/mps-player/src/player.rs b/mps-player/src/player.rs index e007ea9..2939ec4 100644 --- a/mps-player/src/player.rs +++ b/mps-player/src/player.rs @@ -5,9 +5,13 @@ use rodio::{decoder::Decoder, OutputStream, OutputStreamHandle, Sink}; use m3u8_rs::{MediaPlaylist, MediaSegment}; +use super::uri::Uri; + use mps_interpreter::{tokens::MpsTokenReader, MpsFaye, MpsItem}; -use super::PlaybackError; +//use super::PlaybackError; +use super::PlayerError; +use super::UriError; /// Playback functionality for a script. /// This takes the output of the runner and plays or saves it. @@ -20,98 +24,86 @@ pub struct MpsPlayer<'a, T: MpsTokenReader + 'a> { } impl<'a, T: MpsTokenReader + 'a> MpsPlayer<'a, T> { - pub fn new(runner: MpsFaye<'a, T>) -> Result { + pub fn new(runner: MpsFaye<'a, T>) -> Result { let (stream, output_handle) = - OutputStream::try_default().map_err(PlaybackError::from_err)?; + OutputStream::try_default().map_err(PlayerError::from_err_playback)?; Ok(Self { runner: runner, - sink: Sink::try_new(&output_handle).map_err(PlaybackError::from_err)?, + sink: Sink::try_new(&output_handle).map_err(PlayerError::from_err_playback)?, output_stream: stream, output_handle: output_handle, }) } - pub fn play_all(&mut self) -> Result<(), PlaybackError> { - for item in &mut self.runner { + pub fn play_all(&mut self) -> Result<(), PlayerError> { + while let Some(item) = self.runner.next() { self.sink.sleep_until_end(); match item { Ok(music) => { if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { - // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not - let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); + self.append_source(&filename)?; Ok(()) } else { - Err(PlaybackError::from_err( + Err(PlayerError::from_err_playback( "Field `filename` does not exist on item", )) } } - Err(e) => Err(PlaybackError::from_err(e)), + Err(e) => Err(PlayerError::from_err_playback(e)), }?; } self.sink.sleep_until_end(); Ok(()) } - pub fn enqueue_all(&mut self) -> Result, PlaybackError> { + pub fn enqueue_all(&mut self) -> Result, PlayerError> { let mut enqueued = Vec::new(); - for item in &mut self.runner { + while let Some(item) = self.runner.next() { match item { Ok(music) => { enqueued.push(music.clone()); if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { - // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not - let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); + self.append_source(&filename)?; Ok(()) } else { - Err(PlaybackError::from_err( + Err(PlayerError::from_err_playback( "Field `filename` does not exist on item", )) } } - Err(e) => Err(PlaybackError::from_err(e)), + Err(e) => Err(PlayerError::from_err_playback(e)), }?; } Ok(enqueued) } - pub fn enqueue(&mut self, count: usize) -> Result, PlaybackError> { + pub fn enqueue(&mut self, count: usize) -> Result, PlayerError> { let mut items_left = count; let mut enqueued = Vec::with_capacity(count); if items_left == 0 { return Ok(enqueued); } - for item in &mut self.runner { + while let Some(item) = self.runner.next() { match item { Ok(music) => { if let Some(filename) = music.field("filename").and_then(|x| x.to_owned().to_str()) { enqueued.push(music.clone()); - // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not - let file = fs::File::open(filename).map_err(PlaybackError::from_err)?; - let stream = io::BufReader::new(file); - let source = Decoder::new(stream).map_err(PlaybackError::from_err)?; - self.sink.append(source); + self.append_source(&filename)?; items_left -= 1; Ok(()) } else { - Err(PlaybackError::from_err( + Err(PlayerError::from_err_playback( "Field `filename` does not exist on item", )) } } - Err(e) => Err(PlaybackError::from_err(e)), + Err(e) => Err(PlayerError::from_err_playback(e)), }?; if items_left == 0 { break; @@ -145,7 +137,7 @@ impl<'a, T: MpsTokenReader + 'a> MpsPlayer<'a, T> { self.sink.empty() } - pub fn save_m3u8(&mut self, w: &mut W) -> Result<(), PlaybackError> { + pub fn save_m3u8(&mut self, w: &mut W) -> Result<(), PlayerError> { let mut playlist = MediaPlaylist { version: 6, ..Default::default() @@ -165,15 +157,15 @@ impl<'a, T: MpsTokenReader + 'a> MpsPlayer<'a, T> { }); Ok(()) } else { - Err(PlaybackError::from_err( + Err(PlayerError::from_err_playback( "Field `filename` does not exist on item", )) } } - Err(e) => Err(PlaybackError::from_err(e)), + Err(e) => Err(PlayerError::from_err_playback(e)), }?; } - playlist.write_to(w).map_err(PlaybackError::from_err) + playlist.write_to(w).map_err(PlayerError::from_err_playback) } pub fn is_paused(&self) -> bool { @@ -184,12 +176,12 @@ impl<'a, T: MpsTokenReader + 'a> MpsPlayer<'a, T> { self.sink.set_volume(volume); } - pub fn new_sink(&mut self) -> Result<(), PlaybackError> { + pub fn new_sink(&mut self) -> Result<(), PlayerError> { let is_paused = self.sink.is_paused(); let volume = self.sink.volume(); self.stop(); - self.sink = Sink::try_new(&self.output_handle).map_err(PlaybackError::from_err)?; + self.sink = Sink::try_new(&self.output_handle).map_err(PlayerError::from_err_playback)?; if is_paused { self.sink.pause(); @@ -197,6 +189,32 @@ impl<'a, T: MpsTokenReader + 'a> MpsPlayer<'a, T> { self.sink.set_volume(volume); Ok(()) } + + fn append_source(&mut self, filename: &str) -> Result<(), PlayerError> { + let uri = Uri::new(filename); + match uri.scheme() { + Some(s) => match &s.to_lowercase() as &str { + "file:" => { + let file = fs::File::open(uri.path()).map_err(PlayerError::from_err_playback)?; + let stream = io::BufReader::new(file); + let source = Decoder::new(stream).map_err(PlayerError::from_err_playback)?; + self.sink.append(source); + Ok(()) + }, + //TODO "mpd:" => {}, + scheme => Err(UriError::Unsupported(scheme.to_owned()).into()) + }, + None => { + //default + // NOTE: Default rodio::Decoder hangs here when decoding large files, but symphonia does not + let file = fs::File::open(uri.path()).map_err(PlayerError::from_err_playback)?; + let stream = io::BufReader::new(file); + let source = Decoder::new(stream).map_err(PlayerError::from_err_playback)?; + self.sink.append(source); + Ok(()) + } + } + } } #[inline] @@ -226,7 +244,7 @@ mod tests { #[allow(dead_code)] //#[test] - fn play_cursor() -> Result<(), PlaybackError> { + fn play_cursor() -> Result<(), PlayerError> { let cursor = io::Cursor::new("sql(`SELECT * FROM songs JOIN artists ON songs.artist = artists.artist_id WHERE artists.name like 'thundercat'`);"); let runner = MpsFaye::with_stream(cursor); let mut player = MpsPlayer::new(runner)?; @@ -234,7 +252,7 @@ mod tests { } #[test] - fn playlist() -> Result<(), PlaybackError> { + fn playlist() -> Result<(), PlayerError> { let cursor = io::Cursor::new("sql(`SELECT * FROM songs JOIN artists ON songs.artist = artists.artist_id WHERE artists.name like 'thundercat'`);"); let runner = MpsFaye::with_stream(cursor); let mut player = MpsPlayer::new(runner)?; diff --git a/mps-player/src/player_wrapper.rs b/mps-player/src/player_wrapper.rs index 43f26ed..0f4e97d 100644 --- a/mps-player/src/player_wrapper.rs +++ b/mps-player/src/player_wrapper.rs @@ -5,7 +5,7 @@ use mps_interpreter::tokens::MpsTokenReader; use mps_interpreter::MpsItem; use super::MpsPlayer; -use super::PlaybackError; +use super::PlayerError; /// A wrapper around MpsPlayer so that playback can occur on a different thread. /// This allows for message passing between the player and controller. @@ -212,7 +212,7 @@ impl ControlAction { #[derive(Clone, Debug)] pub enum PlayerAction { Acknowledge(ControlAction), - Exception(PlaybackError), + Exception(PlayerError), End, Empty, } diff --git a/mps-player/src/uri.rs b/mps-player/src/uri.rs new file mode 100644 index 0000000..22cf5f1 --- /dev/null +++ b/mps-player/src/uri.rs @@ -0,0 +1,29 @@ +/// A crappy Uri parser. +/// More forgiving than regular ones so it can accept raw filepaths. +pub(crate) struct Uri(S); + +impl<'a> Uri<&'a str> { + pub fn new(s: &'a str) -> Self { + Self(s) + } + + pub fn scheme(&self) -> Option<&'a str> { + self.0.find("//").map(|end| self.0.get(0..end).unwrap()) + } + + pub fn path(&self) -> &'a str { + match self.0.find("//") { + Some(end) => { + // proper URI + if let Some(query_start) = self.0.find("?") { + self.0.get(end+2..query_start).unwrap() + } else if let Some(frag_start) = self.0.find("#") { + self.0.get(end+2..frag_start).unwrap() + } else { + self.0.get(end+2..).unwrap() + } + }, + None => self.0 + } + } +} diff --git a/src/main.rs b/src/main.rs index dc5839d..1bc3de3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,10 +55,10 @@ use std::io; use std::path::PathBuf; use mps_interpreter::MpsFaye; -use mps_player::{MpsController, MpsPlayer, PlaybackError}; +use mps_player::{MpsController, MpsPlayer, PlayerError}; #[allow(dead_code)] -fn play_cursor() -> Result<(), PlaybackError> { +fn play_cursor() -> Result<(), PlayerError> { let cursor = io::Cursor::<&'static str>::new("sql(`SELECT * FROM songs JOIN artists ON songs.artist = artists.artist_id WHERE artists.name like 'thundercat'`);"); let runner = MpsFaye::with_stream(cursor); let mut player = MpsPlayer::new(runner)?; diff --git a/src/repl.rs b/src/repl.rs index d32a91d..9e6f1af 100644 --- a/src/repl.rs +++ b/src/repl.rs @@ -434,8 +434,8 @@ fn display_history_line(state: &mut ReplState, args: &CliArgs) { } #[inline(always)] -fn error_prompt(error: mps_player::PlaybackError, args: &CliArgs) { - eprintln!("E{}{}", args.prompt, error.message()); +fn error_prompt(error: mps_player::PlayerError, args: &CliArgs) { + eprintln!("E{}{}", args.prompt, error); } fn repl_commands(command_str: &str) {