Browse Source

Fix build on latest rust.

Paul Lietar 10 years ago
parent
commit
267ccbe65e
14 changed files with 290 additions and 256 deletions
  1. 118 75
      Cargo.lock
  2. 17 15
      Cargo.toml
  3. 23 23
      src/audio_file.rs
  4. 18 21
      src/audio_key.rs
  5. 3 4
      src/connection.rs
  6. 6 6
      src/lib.rs
  7. 3 5
      src/main.rs
  8. 26 35
      src/mercury.rs
  9. 10 9
      src/metadata.rs
  10. 15 16
      src/player.rs
  11. 26 24
      src/session.rs
  12. 20 18
      src/spirc.rs
  13. 3 3
      src/util/spotify_id.rs
  14. 2 2
      src/util/zerofile.rs

+ 118 - 75
Cargo.lock

@@ -2,27 +2,51 @@
 name = "librespot"
 name = "librespot"
 version = "0.1.0"
 version = "0.1.0"
 dependencies = [
 dependencies = [
- "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "getopts 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bit-set 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "clippy 0.0.12 (git+https://github.com/Manishearth/rust-clippy.git)",
+ "eventual 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "librespot-protocol 0.1.0",
  "librespot-protocol 0.1.0",
  "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "mod_path 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "portaudio 0.1.2 (git+https://github.com/mvdnes/portaudio-rs)",
  "portaudio 0.1.2 (git+https://github.com/mvdnes/portaudio-rs)",
  "protobuf 1.0.1 (git+https://github.com/plietar/rust-protobuf.git)",
  "protobuf 1.0.1 (git+https://github.com/plietar/rust-protobuf.git)",
  "protobuf_macros 0.1.0 (git+https://github.com/plietar/rust-protobuf-macros.git)",
  "protobuf_macros 0.1.0 (git+https://github.com/plietar/rust-protobuf-macros.git)",
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
+ "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rpassword 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rpassword 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-crypto 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-crypto 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
  "rust-gmp 0.2.0 (git+https://github.com/plietar/rust-gmp.git)",
  "rust-gmp 0.2.0 (git+https://github.com/plietar/rust-gmp.git)",
  "shannon 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
  "shannon 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
- "tempfile 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
- "vergen 0.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "vorbis 0.0.11 (git+https://github.com/plietar/vorbis-rs)",
+ "tempfile 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vergen 0.0.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "vorbis 0.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "advapi32-sys"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
+[[package]]
+name = "bit-set"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bit-vec 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 [[package]]
 name = "bitflags"
 name = "bitflags"
 version = "0.1.1"
 version = "0.1.1"
@@ -35,39 +59,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
 name = "byteorder"
 name = "byteorder"
-version = "0.3.11"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
-name = "gcc"
-version = "0.3.8"
+name = "clippy"
+version = "0.0.12"
+source = "git+https://github.com/Manishearth/rust-clippy.git#d3da9f6c81dd3e026bd679c09cea1d6b337ccd25"
+
+[[package]]
+name = "eventual"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syncbox 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 
 [[package]]
 [[package]]
-name = "getopts"
-version = "0.2.11"
+name = "gcc"
+version = "0.3.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "log 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
+[[package]]
+name = "getopts"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 [[package]]
 name = "kernel32-sys"
 name = "kernel32-sys"
-version = "0.1.2"
+version = "0.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "lazy_static"
 name = "lazy_static"
-version = "0.1.11"
+version = "0.1.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
 name = "libc"
 name = "libc"
-version = "0.1.8"
+version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
@@ -80,10 +120,10 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "log"
 name = "log"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -93,11 +133,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
 name = "num"
 name = "num"
-version = "0.1.25"
+version = "0.1.27"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -105,8 +145,8 @@ name = "ogg-sys"
 version = "0.0.9"
 version = "0.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
@@ -121,7 +161,7 @@ version = "0.1.2"
 source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
 source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
 dependencies = [
 dependencies = [
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "portaudio_sys 0.1.0 (git+https://github.com/mvdnes/portaudio-rs)",
  "portaudio_sys 0.1.0 (git+https://github.com/mvdnes/portaudio-rs)",
 ]
 ]
 
 
@@ -130,7 +170,7 @@ name = "portaudio_sys"
 version = "0.1.0"
 version = "0.1.0"
 source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
 source = "git+https://github.com/mvdnes/portaudio-rs#7c6d10f5edda0094cc33b682d88c3a6ea4919b9f"
 dependencies = [
 dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
@@ -142,14 +182,16 @@ source = "git+https://github.com/plietar/rust-protobuf.git#dae87e292a52a66da7f78
 [[package]]
 [[package]]
 name = "protobuf_macros"
 name = "protobuf_macros"
 version = "0.1.0"
 version = "0.1.0"
-source = "git+https://github.com/plietar/rust-protobuf-macros.git#3b49de3937a34b7a21be1d13caea4348a93c6de4"
+source = "git+https://github.com/plietar/rust-protobuf-macros.git#2b6a8129e015945300cb2bb7efae2ed78042ed48"
 
 
 [[package]]
 [[package]]
 name = "rand"
 name = "rand"
-version = "0.3.8"
+version = "0.3.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -162,10 +204,10 @@ name = "rpassword"
 version = "0.0.5"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "termios 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "termios 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -173,24 +215,24 @@ name = "rust-crypto"
 version = "0.2.31"
 version = "0.2.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "rust-gmp"
 name = "rust-gmp"
 version = "0.2.0"
 version = "0.2.0"
-source = "git+https://github.com/plietar/rust-gmp.git#cc003c224559f6035cd34a7ed5c6284a49785816"
+source = "git+https://github.com/plietar/rust-gmp.git#d1bb4448fdbfa2505edadb83b6aac6257fe08ba2"
 dependencies = [
 dependencies = [
- "num 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "rustc-serialize"
 name = "rustc-serialize"
-version = "0.3.15"
+version = "0.3.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
@@ -198,7 +240,7 @@ name = "shannon"
 version = "0.1.0"
 version = "0.1.0"
 source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
 source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
 dependencies = [
 dependencies = [
- "byteorder 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
  "readall 0.1.0 (git+https://github.com/plietar/rust-readall.git)",
  "shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
  "shannon-sys 0.1.0 (git+https://github.com/plietar/rust-shannon.git)",
 ]
 ]
@@ -208,18 +250,27 @@ name = "shannon-sys"
 version = "0.1.0"
 version = "0.1.0"
 source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
 source = "git+https://github.com/plietar/rust-shannon.git#c6be8a879a523a77d81c50df46faa891b76fea25"
 dependencies = [
 dependencies = [
- "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syncbox"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "tempfile"
 name = "tempfile"
-version = "1.0.0"
+version = "1.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -227,34 +278,34 @@ name = "termios"
 version = "0.0.5"
 version = "0.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "time"
 name = "time"
-version = "0.1.30"
+version = "0.1.32"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "kernel32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "vergen"
 name = "vergen"
-version = "0.0.13"
+version = "0.0.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
  "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)",
+ "time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "vorbis"
 name = "vorbis"
-version = "0.0.11"
-source = "git+https://github.com/plietar/vorbis-rs#78058c3341832969030f49cbc4b8bc9deb376776"
+version = "0.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbisfile-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbisfile-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -265,8 +316,8 @@ name = "vorbis-sys"
 version = "0.0.8"
 version = "0.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 ]
@@ -276,8 +327,8 @@ name = "vorbisfile-sys"
 version = "0.0.8"
 version = "0.0.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
 dependencies = [
- "gcc 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "ogg-sys 0.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "vorbis-sys 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -285,19 +336,11 @@ dependencies = [
 
 
 [[package]]
 [[package]]
 name = "winapi"
 name = "winapi"
-version = "0.1.23"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "libc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "winapi"
-version = "0.2.1"
+version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 
 [[package]]
 [[package]]
 name = "winapi-build"
 name = "winapi-build"
-version = "0.1.0"
+version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 

+ 17 - 15
Cargo.toml

@@ -16,17 +16,22 @@ path = "src/main.rs"
 path = "protocol"
 path = "protocol"
 
 
 [dependencies]
 [dependencies]
-mod_path = "*"
-byteorder = "*"
-num = "*"
-rand = "*"
-lazy_static = "0.1.*"
-rust-crypto = "*"
-time = "*"
-tempfile = "*"
-rpassword = "*"
-getopts = "0.2.4"
+bit-set     = "~0.2.0"
+byteorder   = "~0.3.13"
+eventual    = "~0.1.4"
+getopts     = "~0.2.14"
+lazy_static = "~0.1.14"
+mod_path    = "~0.1.5"
+num         = "~0.1.27"
+rand        = "~0.3.11"
+rpassword   = "~0.0.5"
+rust-crypto = "~0.2.31"
+time        = "~0.1.32"
+tempfile    = "~1.1.1"
+vorbis      = "~0.0.12"
 
 
+[dependencies.clippy]
+git = "https://github.com/Manishearth/rust-clippy.git"
 [dependencies.protobuf]
 [dependencies.protobuf]
 git = "https://github.com/plietar/rust-protobuf.git"
 git = "https://github.com/plietar/rust-protobuf.git"
 [dependencies.protobuf_macros]
 [dependencies.protobuf_macros]
@@ -35,12 +40,9 @@ git = "https://github.com/plietar/rust-protobuf-macros.git"
 git = "https://github.com/plietar/rust-gmp.git"
 git = "https://github.com/plietar/rust-gmp.git"
 [dependencies.shannon]
 [dependencies.shannon]
 git = "https://github.com/plietar/rust-shannon.git"
 git = "https://github.com/plietar/rust-shannon.git"
-[dependencies.readall]
-git = "https://github.com/plietar/rust-readall.git"
 [dependencies.portaudio]
 [dependencies.portaudio]
 git = "https://github.com/mvdnes/portaudio-rs"
 git = "https://github.com/mvdnes/portaudio-rs"
-[dependencies.vorbis]
-git = "https://github.com/plietar/vorbis-rs"
 
 
 [build-dependencies]
 [build-dependencies]
-vergen = "*"
+vergen = "~0.0.16"
+

+ 23 - 23
src/audio_file.rs

@@ -1,6 +1,6 @@
+use bit_set::BitSet;
 use byteorder::{ByteOrder, BigEndian};
 use byteorder::{ByteOrder, BigEndian};
 use std::cmp::min;
 use std::cmp::min;
-use std::collections::BitSet;
 use std::sync::{Arc, Condvar, Mutex};
 use std::sync::{Arc, Condvar, Mutex};
 use std::sync::mpsc::{self, TryRecvError};
 use std::sync::mpsc::{self, TryRecvError};
 use std::thread;
 use std::thread;
@@ -9,27 +9,24 @@ use std::io::{self, Read, Write, Seek, SeekFrom};
 use std::path::PathBuf;
 use std::path::PathBuf;
 use tempfile::TempFile;
 use tempfile::TempFile;
 
 
-use stream::StreamEvent;
 use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing};
 use util::{FileId, IgnoreExt, ZeroFile, mkdir_existing};
 use session::Session;
 use session::Session;
+use stream::StreamEvent;
 
 
 const CHUNK_SIZE : usize = 0x20000;
 const CHUNK_SIZE : usize = 0x20000;
 
 
-pub enum AudioFile<'s> {
+pub enum AudioFile {
     Direct(fs::File),
     Direct(fs::File),
-    Loading(AudioFileLoading<'s>)
+    Loading(AudioFileLoading)
 }
 }
 
 
-pub struct AudioFileLoading<'s> {
+pub struct AudioFileLoading {
     read_file: TempFile,
     read_file: TempFile,
 
 
     position: u64,
     position: u64,
     seek: mpsc::Sender<u64>,
     seek: mpsc::Sender<u64>,
 
 
     shared: Arc<AudioFileShared>,
     shared: Arc<AudioFileShared>,
-
-    #[allow(dead_code)]
-    thread: thread::JoinGuard<'s, ()>,
 }
 }
 
 
 struct AudioFileShared {
 struct AudioFileShared {
@@ -40,7 +37,7 @@ struct AudioFileShared {
     bitmap: Mutex<BitSet>,
     bitmap: Mutex<BitSet>,
 }
 }
 
 
-impl <'s> AudioFileLoading<'s> {
+impl AudioFileLoading {
     fn new(session: &Session, file_id: FileId) -> AudioFileLoading {
     fn new(session: &Session, file_id: FileId) -> AudioFileLoading {
         let mut files_iter = TempFile::shared(2).unwrap().into_iter();
         let mut files_iter = TempFile::shared(2).unwrap().into_iter();
         let read_file = files_iter.next().unwrap();
         let read_file = files_iter.next().unwrap();
@@ -70,17 +67,20 @@ impl <'s> AudioFileLoading<'s> {
 
 
         let (seek_tx, seek_rx) = mpsc::channel();
         let (seek_tx, seek_rx) = mpsc::channel();
 
 
+        let _shared = shared.clone();
+        let _session = session.clone();
+
+        thread::spawn(move || {
+            AudioFileLoading::fetch(&_session, _shared, write_file, seek_rx)
+        });
+
         AudioFileLoading {
         AudioFileLoading {
             read_file: read_file,
             read_file: read_file,
 
 
             position: 0,
             position: 0,
             seek: seek_tx,
             seek: seek_tx,
 
 
-            shared: shared.clone(),
-
-            thread: thread::scoped(move || {
-                AudioFileLoading::fetch(session, shared, write_file, seek_rx)
-            })
+            shared: shared
         }
         }
     }
     }
 
 
@@ -155,7 +155,7 @@ impl <'s> AudioFileLoading<'s> {
     }
     }
 }
 }
 
 
-impl <'s> Read for AudioFileLoading<'s> {
+impl Read for AudioFileLoading {
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
         let index = self.position as usize / CHUNK_SIZE;
         let index = self.position as usize / CHUNK_SIZE;
         let offset = self.position as usize % CHUNK_SIZE;
         let offset = self.position as usize % CHUNK_SIZE;
@@ -167,15 +167,15 @@ impl <'s> Read for AudioFileLoading<'s> {
         }
         }
         drop(bitmap);
         drop(bitmap);
 
 
-        let len = try!(self.read_file.read(&mut output[..len]));
+        let read_len = try!(self.read_file.read(&mut output[..len]));
 
 
-        self.position += len as u64;
+        self.position += read_len as u64;
 
 
-        Ok(len)
+        Ok(read_len)
     }
     }
 }
 }
 
 
-impl <'s> Seek for AudioFileLoading<'s> {
+impl Seek for AudioFileLoading {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
     fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
         self.position = try!(self.read_file.seek(pos));
         self.position = try!(self.read_file.seek(pos));
 
 
@@ -189,7 +189,7 @@ impl <'s> Seek for AudioFileLoading<'s> {
     }
     }
 }
 }
 
 
-impl <'s> Read for AudioFile<'s> {
+impl Read for AudioFile {
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
         match *self {
         match *self {
             AudioFile::Direct(ref mut file) => file.read(output),
             AudioFile::Direct(ref mut file) => file.read(output),
@@ -198,7 +198,7 @@ impl <'s> Read for AudioFile<'s> {
     }
     }
 }
 }
 
 
-impl <'s> Seek for AudioFile<'s> {
+impl Seek for AudioFile {
     fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
     fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
         match *self {
         match *self {
             AudioFile::Direct(ref mut file) => file.seek(pos),
             AudioFile::Direct(ref mut file) => file.seek(pos),
@@ -215,7 +215,7 @@ impl AudioFileManager {
 
 
     pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
     pub fn cache_dir(session: &Session, file_id: FileId) -> PathBuf {
         let name = file_id.to_base16();
         let name = file_id.to_base16();
-        session.config.cache_location.join(&name[0..2])
+        session.0.config.cache_location.join(&name[0..2])
     }
     }
 
 
     pub fn cache_path(session: &Session, file_id: FileId) -> PathBuf {
     pub fn cache_path(session: &Session, file_id: FileId) -> PathBuf {
@@ -223,7 +223,7 @@ impl AudioFileManager {
         AudioFileManager::cache_dir(session, file_id).join(&name[2..])
         AudioFileManager::cache_dir(session, file_id).join(&name[2..])
     }
     }
 
 
-    pub fn request<'a> (&mut self, session: &'a Session, file_id: FileId) -> AudioFile<'a> {
+    pub fn request (&mut self, session: &Session, file_id: FileId) -> AudioFile {
         match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
         match fs::File::open(AudioFileManager::cache_path(session, file_id)) {
             Ok(f) => AudioFile::Direct(f),
             Ok(f) => AudioFile::Direct(f),
             Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id))
             Err(..) => AudioFile::Loading(AudioFileLoading::new(session, file_id))

+ 18 - 21
src/audio_key.rs

@@ -1,11 +1,10 @@
-use std::collections::{HashMap, LinkedList};
-use std::sync::{mpsc, Future};
-use std::io::{Cursor, Write};
 use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
 use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
-use readall::ReadAllExt;
+use eventual;
+use std::collections::HashMap;
+use std::io::{Cursor, Read, Write};
 use std::mem;
 use std::mem;
 
 
-use util::{SpotifyId, FileId, IgnoreExt};
+use util::{SpotifyId, FileId};
 use session::Session;
 use session::Session;
 use connection::PacketHandler;
 use connection::PacketHandler;
 
 
@@ -15,7 +14,7 @@ pub type AudioKey = [u8; 16];
 struct AudioKeyId(SpotifyId, FileId);
 struct AudioKeyId(SpotifyId, FileId);
 
 
 enum AudioKeyStatus {
 enum AudioKeyStatus {
-    Loading(LinkedList<mpsc::Sender<AudioKey>>),
+    Loading(Vec<eventual::Complete<AudioKey, ()>>),
     Loaded(AudioKey)
     Loaded(AudioKey)
 }
 }
 
 
@@ -35,17 +34,17 @@ impl AudioKeyManager {
     }
     }
 
 
     pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
     pub fn request(&mut self, session: &Session, track: SpotifyId, file: FileId)
-        -> Future<AudioKey> {
+        -> eventual::Future<AudioKey, ()> {
 
 
         let id = AudioKeyId(track, file);
         let id = AudioKeyId(track, file);
-        self.cache.get_mut(&id).map(|status| match status {
-            &mut AudioKeyStatus::Loaded(key) => {
-                Future::from_value(key.clone())
+        self.cache.get_mut(&id).map(|status| match *status {
+            AudioKeyStatus::Loaded(key) => {
+                eventual::Future::of(key.clone())
             }
             }
-            &mut AudioKeyStatus::Loading(ref mut req) => {
-                let (tx, rx) = mpsc::channel();
-                req.push_front(tx);
-                Future::from_receiver(rx)
+            AudioKeyStatus::Loading(ref mut req) => {
+                let (tx, rx) = eventual::Future::pair();
+                req.push(tx);
+                rx
             }
             }
         }).unwrap_or_else(|| {
         }).unwrap_or_else(|| {
             let seq = self.next_seq;
             let seq = self.next_seq;
@@ -61,11 +60,9 @@ impl AudioKeyManager {
 
 
             self.pending.insert(seq, id.clone());
             self.pending.insert(seq, id.clone());
 
 
-            let (tx, rx) = mpsc::channel();
-            let mut req = LinkedList::new();
-            req.push_front(tx);
-            self.cache.insert(id, AudioKeyStatus::Loading(req));
-            Future::from_receiver(rx)
+            let (tx, rx) = eventual::Future::pair();
+            self.cache.insert(id, AudioKeyStatus::Loading(vec!{ tx }));
+            rx
         })
         })
     }
     }
 }
 }
@@ -77,14 +74,14 @@ impl PacketHandler for AudioKeyManager {
         let mut data = Cursor::new(data);
         let mut data = Cursor::new(data);
         let seq = data.read_u32::<BigEndian>().unwrap();
         let seq = data.read_u32::<BigEndian>().unwrap();
         let mut key = [0u8; 16];
         let mut key = [0u8; 16];
-        data.read_all(&mut key).unwrap();
+        data.read_exact(&mut key).unwrap();
 
 
         if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
         if let Some(status) = self.pending.remove(&seq).and_then(|id| { self.cache.get_mut(&id) }) {
             let status = mem::replace(status, AudioKeyStatus::Loaded(key));
             let status = mem::replace(status, AudioKeyStatus::Loaded(key));
 
 
             if let AudioKeyStatus::Loading(cbs) = status {
             if let AudioKeyStatus::Loading(cbs) = status {
                 for cb in cbs {
                 for cb in cbs {
-                    cb.send(key).ignore();
+                    cb.complete(key);
                 }
                 }
             }
             }
         }
         }

+ 3 - 4
src/connection.rs

@@ -1,9 +1,8 @@
 use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
 use byteorder::{self, BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
-use readall::ReadAllExt;
 use shannon::ShannonStream;
 use shannon::ShannonStream;
 use std::convert;
 use std::convert;
 use std::io;
 use std::io;
-use std::io::Write;
+use std::io::{Read, Write};
 use std::net::TcpStream;
 use std::net::TcpStream;
 use std::result;
 use std::result;
 
 
@@ -70,7 +69,7 @@ impl PlainConnection {
         let mut buffer = vec![0u8; size];
         let mut buffer = vec![0u8; size];
 
 
         BigEndian::write_u32(&mut buffer, size as u32);
         BigEndian::write_u32(&mut buffer, size as u32);
-        try!(self.stream.read_all(&mut buffer[4..]));
+        try!(self.stream.read_exact(&mut buffer[4..]));
 
 
         Ok(buffer)
         Ok(buffer)
     }
     }
@@ -98,7 +97,7 @@ impl CipherConnection {
         let size = try!(self.stream.read_u16::<BigEndian>()) as usize;
         let size = try!(self.stream.read_u16::<BigEndian>()) as usize;
 
 
         let mut data = vec![0; size];
         let mut data = vec![0; size];
-        try!(self.stream.read_all(&mut data));
+        try!(self.stream.read_exact(&mut data));
 
 
         try!(self.stream.finish_recv());
         try!(self.stream.finish_recv());
 
 

+ 6 - 6
src/lib.rs

@@ -1,25 +1,25 @@
 #![crate_name = "librespot"]
 #![crate_name = "librespot"]
 
 
-#![feature(plugin,scoped,zero_one,iter_arith,slice_position_elem,slice_bytes,bitset,arc_weak,append,future,mpsc_select)]
-#![allow(deprecated)]
-//#![allow(unused_imports,dead_code)]
+#![feature(plugin,read_exact,zero_one,iter_arith,slice_bytes,arc_weak,append,mpsc_select)]
+#![allow(needless_return)]
 
 
+#![plugin(clippy)]
 #![plugin(protobuf_macros)]
 #![plugin(protobuf_macros)]
 #[macro_use] extern crate lazy_static;
 #[macro_use] extern crate lazy_static;
 
 
-
+extern crate bit_set;
 extern crate byteorder;
 extern crate byteorder;
 extern crate crypto;
 extern crate crypto;
+extern crate eventual;
 extern crate gmp;
 extern crate gmp;
 extern crate num;
 extern crate num;
 extern crate portaudio;
 extern crate portaudio;
 extern crate protobuf;
 extern crate protobuf;
 extern crate shannon;
 extern crate shannon;
 extern crate rand;
 extern crate rand;
-extern crate readall;
-extern crate vorbis;
 extern crate time;
 extern crate time;
 extern crate tempfile;
 extern crate tempfile;
+extern crate vorbis;
 
 
 extern crate librespot_protocol;
 extern crate librespot_protocol;
 
 

+ 3 - 5
src/main.rs

@@ -1,4 +1,3 @@
-#![feature(scoped)]
 #![feature(result_expect)]
 #![feature(result_expect)]
 #![allow(deprecated)]
 #![allow(deprecated)]
 
 
@@ -71,9 +70,10 @@ fn main() {
     session.login(username.clone(), password);
     session.login(username.clone(), password);
     session.poll();
     session.poll();
 
 
-    let poll_thread = thread::scoped(|| {
+    let _session = session.clone();
+    thread::spawn(move || {
         loop {
         loop {
-            session.poll();
+            _session.poll();
         }
         }
     });
     });
 
 
@@ -81,7 +81,5 @@ fn main() {
 
 
     let mut spirc_manager = SpircManager::new(&session, player, username, name);
     let mut spirc_manager = SpircManager::new(&session, player, username, name);
     spirc_manager.run();
     spirc_manager.run();
-
-    poll_thread.join();
 }
 }
 
 

+ 26 - 35
src/mercury.rs

@@ -1,11 +1,10 @@
 use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
 use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
+use eventual;
 use protobuf::{self, Message};
 use protobuf::{self, Message};
-use readall::ReadAllExt;
-use std::collections::{HashMap, LinkedList};
+use std::collections::HashMap;
 use std::io::{Cursor, Read, Write};
 use std::io::{Cursor, Read, Write};
-use std::fmt;
 use std::mem::replace;
 use std::mem::replace;
-use std::sync::{mpsc, Future};
+use std::sync::mpsc;
 
 
 use librespot_protocol as protocol;
 use librespot_protocol as protocol;
 use session::Session;
 use session::Session;
@@ -30,13 +29,13 @@ pub struct MercuryRequest {
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct MercuryResponse {
 pub struct MercuryResponse {
     pub uri: String,
     pub uri: String,
-    pub payload: LinkedList<Vec<u8>>
+    pub payload: Vec<Vec<u8>>
 }
 }
 
 
 pub struct MercuryPending {
 pub struct MercuryPending {
-    parts: LinkedList<Vec<u8>>,
+    parts: Vec<Vec<u8>>,
     partial: Option<Vec<u8>>,
     partial: Option<Vec<u8>>,
-    callback: Option<mpsc::Sender<MercuryResponse>>
+    callback: Option<eventual::Complete<MercuryResponse, ()>>
 }
 }
 
 
 pub struct MercuryManager {
 pub struct MercuryManager {
@@ -45,14 +44,14 @@ pub struct MercuryManager {
     subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>,
     subscriptions: HashMap<String, mpsc::Sender<MercuryResponse>>,
 }
 }
 
 
-impl fmt::Display for MercuryMethod {
-    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
-        formatter.write_str(match *self {
+impl ToString for MercuryMethod {
+    fn to_string(&self) -> String {
+        match *self {
             MercuryMethod::GET => "GET",
             MercuryMethod::GET => "GET",
             MercuryMethod::SUB => "SUB",
             MercuryMethod::SUB => "SUB",
             MercuryMethod::UNSUB => "UNSUB",
             MercuryMethod::UNSUB => "UNSUB",
             MercuryMethod::SEND => "SEND"
             MercuryMethod::SEND => "SEND"
-        })
+        }.to_owned()
     }
     }
 }
 }
 
 
@@ -66,7 +65,7 @@ impl MercuryManager {
     }
     }
 
 
     pub fn request(&mut self, session: &Session, req: MercuryRequest)
     pub fn request(&mut self, session: &Session, req: MercuryRequest)
-        -> Future<MercuryResponse> {
+        -> eventual::Future<MercuryResponse, ()> {
 
 
         let mut seq = [0u8; 4];
         let mut seq = [0u8; 4];
         BigEndian::write_u32(&mut seq, self.next_seq);
         BigEndian::write_u32(&mut seq, self.next_seq);
@@ -81,14 +80,14 @@ impl MercuryManager {
 
 
         session.send_packet(cmd, &data).unwrap();
         session.send_packet(cmd, &data).unwrap();
 
 
-        let (tx, rx) = mpsc::channel();
+        let (tx, rx) = eventual::Future::pair();
         self.pending.insert(seq.to_vec(), MercuryPending{
         self.pending.insert(seq.to_vec(), MercuryPending{
-            parts: LinkedList::new(),
+            parts: Vec::new(),
             partial: None,
             partial: None,
             callback: Some(tx),
             callback: Some(tx),
         });
         });
 
 
-        Future::from_receiver(rx)
+        rx
     }
     }
 
 
     pub fn subscribe(&mut self, session: &Session, uri: String)
     pub fn subscribe(&mut self, session: &Session, uri: String)
@@ -109,33 +108,25 @@ impl MercuryManager {
     fn parse_part(mut s: &mut Read) -> Vec<u8> {
     fn parse_part(mut s: &mut Read) -> Vec<u8> {
         let size = s.read_u16::<BigEndian>().unwrap() as usize;
         let size = s.read_u16::<BigEndian>().unwrap() as usize;
         let mut buffer = vec![0; size];
         let mut buffer = vec![0; size];
-        s.read_all(&mut buffer).unwrap();
+        s.read_exact(&mut buffer).unwrap();
 
 
         buffer
         buffer
     }
     }
 
 
     fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) {
     fn complete_request(&mut self, cmd: u8, mut pending: MercuryPending) {
-        let header_data = match pending.parts.pop_front() {
-            Some(data) => data,
-            None => panic!("No header part !")
-        };
-
+        let header_data = pending.parts.remove(0);
         let header : protocol::mercury::Header =
         let header : protocol::mercury::Header =
             protobuf::parse_from_bytes(&header_data).unwrap();
             protobuf::parse_from_bytes(&header_data).unwrap();
 
 
-        let callback = if cmd == 0xb5 {
-            self.subscriptions.get(header.get_uri())
-        } else {
-            pending.callback.as_ref()
+        let response = MercuryResponse {
+            uri: header.get_uri().to_owned(),
+            payload: pending.parts
         };
         };
 
 
-        if let Some(ref ch) = callback {
-             // Ignore send error.
-             // It simply means the receiver was closed
-            ch.send(MercuryResponse{
-                uri: header.get_uri().to_string(),
-                payload: pending.parts
-            }).ignore();
+        if cmd == 0xb5 {
+            self.subscriptions.get(header.get_uri()).map(|ch| ch.send(response).ignore());
+        } else {
+            pending.callback.map(|cb| cb.complete(response));
         }
         }
     }
     }
 
 
@@ -173,7 +164,7 @@ impl PacketHandler for MercuryManager {
         let seq = {
         let seq = {
             let seq_length = packet.read_u16::<BigEndian>().unwrap() as usize;
             let seq_length = packet.read_u16::<BigEndian>().unwrap() as usize;
             let mut seq = vec![0; seq_length];
             let mut seq = vec![0; seq_length];
-            packet.read_all(&mut seq).unwrap();
+            packet.read_exact(&mut seq).unwrap();
             seq
             seq
         };
         };
         let flags = packet.read_u8().unwrap();
         let flags = packet.read_u8().unwrap();
@@ -183,7 +174,7 @@ impl PacketHandler for MercuryManager {
             pending
             pending
         } else if cmd == 0xb5 {
         } else if cmd == 0xb5 {
             MercuryPending {
             MercuryPending {
-                parts: LinkedList::new(),
+                parts: Vec::new(),
                 partial: None,
                 partial: None,
                 callback: None,
                 callback: None,
             }
             }
@@ -202,7 +193,7 @@ impl PacketHandler for MercuryManager {
             if i == count - 1 && (flags == 2) {
             if i == count - 1 && (flags == 2) {
                 pending.partial = Some(part)
                 pending.partial = Some(part)
             } else {
             } else {
-                pending.parts.push_back(part);
+                pending.parts.push(part);
             }
             }
         }
         }
 
 

+ 10 - 9
src/metadata.rs

@@ -1,3 +1,4 @@
+use eventual::Async;
 use protobuf::{self, Message};
 use protobuf::{self, Message};
 use std::any::{Any, TypeId};
 use std::any::{Any, TypeId};
 use std::collections::HashMap;
 use std::collections::HashMap;
@@ -11,7 +12,7 @@ use mercury::{MercuryRequest, MercuryMethod};
 use util::{SpotifyId, FileId};
 use util::{SpotifyId, FileId};
 use session::Session;
 use session::Session;
 
 
-pub trait MetadataTrait : Send + Any + 'static {
+pub trait MetadataTrait : Send + Sized + Any + 'static {
     type Message: protobuf::MessageStatic;
     type Message: protobuf::MessageStatic;
     fn from_msg(msg: &Self::Message) -> Self;
     fn from_msg(msg: &Self::Message) -> Self;
     fn base_url() -> &'static str;
     fn base_url() -> &'static str;
@@ -29,7 +30,7 @@ impl MetadataTrait for Track {
     type Message = protocol::metadata::Track;
     type Message = protocol::metadata::Track;
     fn from_msg(msg: &Self::Message) -> Self {
     fn from_msg(msg: &Self::Message) -> Self {
         Track {
         Track {
-            name: msg.get_name().to_string(),
+            name: msg.get_name().to_owned(),
             album: SpotifyId::from_raw(msg.get_album().get_gid()),
             album: SpotifyId::from_raw(msg.get_album().get_gid()),
             files: msg.get_file().iter()
             files: msg.get_file().iter()
                 .map(|file| {
                 .map(|file| {
@@ -59,7 +60,7 @@ impl MetadataTrait for Album {
     type Message = protocol::metadata::Album;
     type Message = protocol::metadata::Album;
     fn from_msg(msg: &Self::Message) -> Self {
     fn from_msg(msg: &Self::Message) -> Self {
         Album {
         Album {
-            name: msg.get_name().to_string(),
+            name: msg.get_name().to_owned(),
             artists: msg.get_artist().iter()
             artists: msg.get_artist().iter()
                 .map(|a| SpotifyId::from_raw(a.get_gid()))
                 .map(|a| SpotifyId::from_raw(a.get_gid()))
                 .collect(),
                 .collect(),
@@ -89,7 +90,7 @@ impl MetadataTrait for Artist {
     type Message = protocol::metadata::Artist;
     type Message = protocol::metadata::Artist;
     fn from_msg(msg: &Self::Message) -> Self {
     fn from_msg(msg: &Self::Message) -> Self {
         Artist {
         Artist {
-            name: msg.get_name().to_string(),
+            name: msg.get_name().to_owned(),
         }
         }
     }
     }
     fn base_url() -> &'static str {
     fn base_url() -> &'static str {
@@ -164,7 +165,7 @@ impl <T: MetadataTrait> MetadataState<T> {
         }
         }
     }
     }
 
 
-    pub fn unwrap<'s>(&'s self) -> &'s T {
+    pub fn unwrap(&self) -> &T {
         match *self {
         match *self {
             MetadataState::Loaded(ref data) => data,
             MetadataState::Loaded(ref data) => data,
             _ => panic!("Not loaded")
             _ => panic!("Not loaded")
@@ -180,7 +181,7 @@ pub enum MetadataRequest {
 }
 }
 
 
 pub struct MetadataManager {
 pub struct MetadataManager {
-    cache: HashMap<(SpotifyId, TypeId), Box<Any + Send>>
+    cache: HashMap<(SpotifyId, TypeId), Box<Any + Send + 'static>>
 }
 }
 
 
 impl MetadataManager {
 impl MetadataManager {
@@ -204,7 +205,7 @@ impl MetadataManager {
                     cond: Condvar::new()
                     cond: Condvar::new()
                 });
                 });
 
 
-                self.cache.insert(key, Box::new(x.downgrade()));
+                self.cache.insert(key, Box::new(Arc::downgrade(&x)));
                 self.load(session, x.clone());
                 self.load(session, x.clone());
                 x
                 x
             })
             })
@@ -219,10 +220,10 @@ impl MetadataManager {
         });
         });
 
 
         thread::spawn(move || {
         thread::spawn(move || {
-            let response = rx.into_inner();
+            let response = rx.await().unwrap();
 
 
             let msg : T::Message = protobuf::parse_from_bytes(
             let msg : T::Message = protobuf::parse_from_bytes(
-                response.payload.front().unwrap()).unwrap();
+                response.payload.first().unwrap()).unwrap();
 
 
             object.set(MetadataState::Loaded(T::from_msg(&msg)));
             object.set(MetadataState::Loaded(T::from_msg(&msg)));
         });
         });

+ 15 - 16
src/player.rs

@@ -1,7 +1,8 @@
+use eventual::Async;
 use portaudio;
 use portaudio;
-use vorbis;
 use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard};
 use std::sync::{mpsc, Mutex, Arc, Condvar, MutexGuard};
 use std::thread;
 use std::thread;
+use vorbis;
 
 
 use metadata::TrackRef;
 use metadata::TrackRef;
 use session::Session;
 use session::Session;
@@ -9,13 +10,10 @@ use audio_decrypt::AudioDecrypt;
 use util::{self, SpotifyId, Subfile};
 use util::{self, SpotifyId, Subfile};
 use spirc::{SpircState, SpircDelegate, PlayStatus};
 use spirc::{SpircState, SpircDelegate, PlayStatus};
 
 
-pub struct Player<'s> {
+pub struct Player {
     state: Arc<(Mutex<PlayerState>, Condvar)>,
     state: Arc<(Mutex<PlayerState>, Condvar)>,
 
 
     commands: mpsc::Sender<PlayerCommand>,
     commands: mpsc::Sender<PlayerCommand>,
-
-    #[allow(dead_code)]
-    thread: thread::JoinGuard<'s, ()>,
 }
 }
 
 
 pub struct PlayerState {
 pub struct PlayerState {
@@ -27,10 +25,9 @@ pub struct PlayerState {
     end_of_track: bool
     end_of_track: bool
 }
 }
 
 
-struct PlayerInternal<'s> {
+struct PlayerInternal {
     state: Arc<(Mutex<PlayerState>, Condvar)>,
     state: Arc<(Mutex<PlayerState>, Condvar)>,
-
-    session: &'s Session,
+    session: Session,
     commands: mpsc::Receiver<PlayerCommand>,
     commands: mpsc::Receiver<PlayerCommand>,
 }
 }
 
 
@@ -42,7 +39,7 @@ enum PlayerCommand {
     Seek(u32)
     Seek(u32)
 }
 }
 
 
-impl <'s> Player<'s> {
+impl Player {
     pub fn new(session: &Session) -> Player {
     pub fn new(session: &Session) -> Player {
         let (cmd_tx, cmd_rx) = mpsc::channel();
         let (cmd_tx, cmd_rx) = mpsc::channel();
 
 
@@ -55,17 +52,18 @@ impl <'s> Player<'s> {
         }), Condvar::new()));
         }), Condvar::new()));
 
 
         let internal = PlayerInternal {
         let internal = PlayerInternal {
-            session: session,
+            session: session.clone(),
             commands: cmd_rx,
             commands: cmd_rx,
             state: state.clone()
             state: state.clone()
         };
         };
 
 
+        thread::spawn(move || {
+            internal.run()
+        });
+
         Player {
         Player {
             commands: cmd_tx,
             commands: cmd_tx,
             state: state,
             state: state,
-            thread: thread::scoped(move || {
-                internal.run()
-            })
         }
         }
     }
     }
 
 
@@ -74,7 +72,7 @@ impl <'s> Player<'s> {
     }
     }
 }
 }
 
 
-impl <'s> PlayerInternal<'s> {
+impl PlayerInternal {
     fn run(self) {
     fn run(self) {
         portaudio::initialize().unwrap();
         portaudio::initialize().unwrap();
 
 
@@ -102,7 +100,8 @@ impl <'s> PlayerInternal<'s> {
 
 
                     let track : TrackRef = self.session.metadata(id);
                     let track : TrackRef = self.session.metadata(id);
                     let file_id = *track.wait().unwrap().files.first().unwrap();
                     let file_id = *track.wait().unwrap().files.first().unwrap();
-                    let key = self.session.audio_key(track.id(), file_id).into_inner();
+
+                    let key = self.session.audio_key(track.id(), file_id).await().unwrap();
                     decoder = Some(
                     decoder = Some(
                         vorbis::Decoder::new(
                         vorbis::Decoder::new(
                         Subfile::new(
                         Subfile::new(
@@ -217,7 +216,7 @@ impl <'s> PlayerInternal<'s> {
     }
     }
 }
 }
 
 
-impl <'s> SpircDelegate for Player<'s> {
+impl SpircDelegate for Player {
     type State = PlayerState;
     type State = PlayerState;
 
 
     fn load(&self, track: SpotifyId,
     fn load(&self, track: SpotifyId,

+ 26 - 24
src/session.rs

@@ -1,8 +1,9 @@
 use crypto::digest::Digest;
 use crypto::digest::Digest;
 use crypto::sha1::Sha1;
 use crypto::sha1::Sha1;
+use eventual::Future;
 use protobuf::{self, Message};
 use protobuf::{self, Message};
 use rand::thread_rng;
 use rand::thread_rng;
-use std::sync::{Mutex, Arc, Future, mpsc};
+use std::sync::{Mutex, Arc, mpsc};
 use std::path::PathBuf;
 use std::path::PathBuf;
 
 
 use connection::{self, PlainConnection, CipherConnection};
 use connection::{self, PlainConnection, CipherConnection};
@@ -26,7 +27,7 @@ pub struct Config {
     pub cache_location: PathBuf,
     pub cache_location: PathBuf,
 }
 }
 
 
-pub struct Session {
+pub struct SessionData {
     pub config: Config,
     pub config: Config,
 
 
     mercury: Mutex<MercuryManager>,
     mercury: Mutex<MercuryManager>,
@@ -38,7 +39,8 @@ pub struct Session {
     tx_connection: Mutex<CipherConnection>,
     tx_connection: Mutex<CipherConnection>,
 }
 }
 
 
-type SessionRef = Arc<Session>;
+#[derive(Clone)]
+pub struct Session(pub Arc<SessionData>);
 
 
 impl Session {
 impl Session {
     pub fn new(mut config: Config) -> Session {
     pub fn new(mut config: Config) -> Session {
@@ -114,7 +116,7 @@ impl Session {
 
 
         let cipher_connection = connection.setup_cipher(shared_keys);
         let cipher_connection = connection.setup_cipher(shared_keys);
 
 
-        Session {
+        Session(Arc::new(SessionData {
             config: config,
             config: config,
 
 
             rx_connection: Mutex::new(cipher_connection.clone()),
             rx_connection: Mutex::new(cipher_connection.clone()),
@@ -125,7 +127,7 @@ impl Session {
             stream: Mutex::new(StreamManager::new()),
             stream: Mutex::new(StreamManager::new()),
             audio_key: Mutex::new(AudioKeyManager::new()),
             audio_key: Mutex::new(AudioKeyManager::new()),
             audio_file: Mutex::new(AudioFileManager::new()),
             audio_file: Mutex::new(AudioFileManager::new()),
-        }
+        }))
     }
     }
 
 
     pub fn login(&self, username: String, password: String) {
     pub fn login(&self, username: String, password: String) {
@@ -138,15 +140,15 @@ impl Session {
             system_info => {
             system_info => {
                 cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
                 cpu_family: protocol::authentication::CpuFamily::CPU_UNKNOWN,
                 os: protocol::authentication::Os::OS_UNKNOWN,
                 os: protocol::authentication::Os::OS_UNKNOWN,
-                system_information_string: "librespot".to_string(),
-                device_id: self.config.device_id.clone()
+                system_information_string: "librespot".to_owned(),
+                device_id: self.0.config.device_id.clone()
             },
             },
             version_string: util::version::version_string(),
             version_string: util::version::version_string(),
             appkey => {
             appkey => {
-                version: self.config.application_key[0] as u32,
-                devkey: self.config.application_key[0x1..0x81].to_vec(),
-                signature: self.config.application_key[0x81..0x141].to_vec(),
-                useragent: self.config.user_agent.clone(),
+                version: self.0.config.application_key[0] as u32,
+                devkey: self.0.config.application_key[0x1..0x81].to_vec(),
+                signature: self.0.config.application_key[0x81..0x141].to_vec(),
+                useragent: self.0.config.user_agent.clone(),
                 callback_hash: vec![0; 20],
                 callback_hash: vec![0; 20],
             }
             }
         });
         });
@@ -156,14 +158,14 @@ impl Session {
 
 
     pub fn poll(&self) {
     pub fn poll(&self) {
         let (cmd, data) =
         let (cmd, data) =
-            self.rx_connection.lock().unwrap().recv_packet().unwrap();
+            self.0.rx_connection.lock().unwrap().recv_packet().unwrap();
 
 
         match cmd {
         match cmd {
             0x4 => self.send_packet(0x49, &data).unwrap(),
             0x4 => self.send_packet(0x49, &data).unwrap(),
             0x4a => (),
             0x4a => (),
-            0x9  => self.stream.lock().unwrap().handle(cmd, data),
-            0xd | 0xe => self.audio_key.lock().unwrap().handle(cmd, data),
-            0xb2...0xb6 => self.mercury.lock().unwrap().handle(cmd, data),
+            0x9  => self.0.stream.lock().unwrap().handle(cmd, data),
+            0xd | 0xe => self.0.audio_key.lock().unwrap().handle(cmd, data),
+            0xb2...0xb6 => self.0.mercury.lock().unwrap().handle(cmd, data),
             0xac => eprintln!("Authentication succeedded"),
             0xac => eprintln!("Authentication succeedded"),
             0xad => eprintln!("Authentication failed"),
             0xad => eprintln!("Authentication failed"),
             _ => ()
             _ => ()
@@ -171,31 +173,31 @@ impl Session {
     }
     }
 
 
     pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> {
     pub fn send_packet(&self, cmd: u8, data: &[u8]) -> connection::Result<()> {
-        self.tx_connection.lock().unwrap().send_packet(cmd, data)
+        self.0.tx_connection.lock().unwrap().send_packet(cmd, data)
     }
     }
     
     
-    pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future<AudioKey> {
-        self.audio_key.lock().unwrap().request(self, track, file)
+    pub fn audio_key(&self, track: SpotifyId, file: FileId) -> Future<AudioKey, ()> {
+        self.0.audio_key.lock().unwrap().request(self, track, file)
     }
     }
 
 
     pub fn audio_file(&self, file: FileId) -> AudioFile {
     pub fn audio_file(&self, file: FileId) -> AudioFile {
-        self.audio_file.lock().unwrap().request(self, file)
+        self.0.audio_file.lock().unwrap().request(self, file)
     }
     }
 
 
     pub fn stream(&self, file: FileId, offset: u32, size: u32) -> mpsc::Receiver<StreamEvent> {
     pub fn stream(&self, file: FileId, offset: u32, size: u32) -> mpsc::Receiver<StreamEvent> {
-        self.stream.lock().unwrap().request(self, file, offset, size)
+        self.0.stream.lock().unwrap().request(self, file, offset, size)
     }
     }
 
 
     pub fn metadata<T: MetadataTrait>(&self, id: SpotifyId) -> MetadataRef<T> {
     pub fn metadata<T: MetadataTrait>(&self, id: SpotifyId) -> MetadataRef<T> {
-        self.metadata.lock().unwrap().get(self, id)
+        self.0.metadata.lock().unwrap().get(self, id)
     }
     }
 
 
-    pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse> {
-        self.mercury.lock().unwrap().request(self, req)
+    pub fn mercury(&self, req: MercuryRequest) -> Future<MercuryResponse, ()> {
+        self.0.mercury.lock().unwrap().request(self, req)
     }
     }
 
 
     pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> {
     pub fn mercury_sub(&self, uri: String) -> mpsc::Receiver<MercuryResponse> {
-        self.mercury.lock().unwrap().subscribe(self, uri)
+        self.0.mercury.lock().unwrap().subscribe(self, uri)
     }
     }
 }
 }
 
 

+ 20 - 18
src/spirc.rs

@@ -1,3 +1,4 @@
+use eventual::Async;
 use protobuf::{self, Message};
 use protobuf::{self, Message};
 use std::sync::{mpsc, MutexGuard};
 use std::sync::{mpsc, MutexGuard};
 
 
@@ -70,7 +71,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
             seq_nr: 0,
             seq_nr: 0,
 
 
             name: name,
             name: name,
-            ident: session.config.device_id.clone(),
+            ident: session.0.config.device_id.clone(),
             device_type: 5,
             device_type: 5,
             can_play: true,
             can_play: true,
 
 
@@ -97,7 +98,8 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
             select! {
             select! {
                 pkt = rx.recv() => {
                 pkt = rx.recv() => {
                     let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(
                     let frame = protobuf::parse_from_bytes::<protocol::spirc::Frame>(
-                        pkt.unwrap().payload.front().unwrap()).unwrap();
+                        pkt.unwrap().payload.first().unwrap()).unwrap();
+
                     println!("{:?} {} {} {} {}",
                     println!("{:?} {} {} {} {}",
                              frame.get_typ(),
                              frame.get_typ(),
                              frame.get_device_state().get_name(),
                              frame.get_device_state().get_name(),
@@ -127,7 +129,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
 
 
     fn handle(&mut self, frame: protocol::spirc::Frame) {
     fn handle(&mut self, frame: protocol::spirc::Frame) {
         if frame.get_recipient().len() > 0 {
         if frame.get_recipient().len() > 0 {
-            self.last_command_ident = frame.get_ident().to_string();
+            self.last_command_ident = frame.get_ident().to_owned();
             self.last_command_msgid = frame.get_seq_nr();
             self.last_command_msgid = frame.get_seq_nr();
         }
         }
         match frame.get_typ() {
         match frame.get_typ() {
@@ -174,12 +176,12 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
         let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), {
         let mut pkt = protobuf_init!(protocol::spirc::Frame::new(), {
             version: 1,
             version: 1,
             ident: self.ident.clone(),
             ident: self.ident.clone(),
-            protocol_version: "2.0.0".to_string(),
+            protocol_version: "2.0.0".to_owned(),
             seq_nr: { self.seq_nr += 1; self.seq_nr  },
             seq_nr: { self.seq_nr += 1; self.seq_nr  },
             typ: protocol::spirc::MessageType::kMessageTypeNotify,
             typ: protocol::spirc::MessageType::kMessageTypeNotify,
             device_state: self.device_state(),
             device_state: self.device_state(),
             recipient: protobuf::RepeatedField::from_vec(
             recipient: protobuf::RepeatedField::from_vec(
-                recipient.map(|r| vec![r.to_string()] ).unwrap_or(vec![])
+                recipient.map(|r| vec![r.to_owned()] ).unwrap_or(vec![])
             ),
             ),
             state_update_id: self.state_update_id as i64
             state_update_id: self.state_update_id as i64
         });
         });
@@ -193,7 +195,7 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
             uri: format!("hm://remote/user/{}", self.username),
             uri: format!("hm://remote/user/{}", self.username),
             content_type: None,
             content_type: None,
             payload: vec![ pkt.write_to_bytes().unwrap() ]
             payload: vec![ pkt.write_to_bytes().unwrap() ]
-        });
+        }).await().unwrap();
     }
     }
 
 
     fn spirc_state(&self) -> protocol::spirc::State {
     fn spirc_state(&self) -> protocol::spirc::State {
@@ -259,23 +261,23 @@ impl <'s, D: SpircDelegate> SpircManager<'s, D> {
                 @{
                 @{
                     typ: protocol::spirc::CapabilityType::kSupportedContexts,
                     typ: protocol::spirc::CapabilityType::kSupportedContexts,
                     stringValue => [
                     stringValue => [
-                        "album".to_string(),
-                        "playlist".to_string(),
-                        "search".to_string(),
-                        "inbox".to_string(),
-                        "toplist".to_string(),
-                        "starred".to_string(),
-                        "publishedstarred".to_string(),
-                        "track".to_string(),
+                        "album".to_owned(),
+                        "playlist".to_owned(),
+                        "search".to_owned(),
+                        "inbox".to_owned(),
+                        "toplist".to_owned(),
+                        "starred".to_owned(),
+                        "publishedstarred".to_owned(),
+                        "track".to_owned(),
                     ]
                     ]
                 },
                 },
                 @{
                 @{
                     typ: protocol::spirc::CapabilityType::kSupportedTypes,
                     typ: protocol::spirc::CapabilityType::kSupportedTypes,
                     stringValue => [
                     stringValue => [
-                        "audio/local".to_string(),
-                        "audio/track".to_string(),
-                        "local".to_string(),
-                        "track".to_string(),
+                        "audio/local".to_owned(),
+                        "audio/track".to_owned(),
+                        "local".to_owned(),
+                        "track".to_owned(),
                     ]
                     ]
                 }
                 }
             ],
             ],

+ 3 - 3
src/util/spotify_id.rs

@@ -19,7 +19,7 @@ impl SpotifyId {
 
 
         let mut n : u128 = std::num::Zero::zero();
         let mut n : u128 = std::num::Zero::zero();
         for c in data {
         for c in data {
-            let d = BASE16_DIGITS.position_elem(c).unwrap() as u8;
+            let d = BASE16_DIGITS.iter().position(|e| e == c).unwrap() as u8;
             n = n * u128::from(16);
             n = n * u128::from(16);
             n = n + u128::from(d);
             n = n + u128::from(d);
         }
         }
@@ -33,7 +33,7 @@ impl SpotifyId {
 
 
         let mut n : u128 = std::num::Zero::zero();
         let mut n : u128 = std::num::Zero::zero();
         for c in data {
         for c in data {
-            let d = BASE62_DIGITS.position_elem(c).unwrap() as u8;
+            let d = BASE62_DIGITS.iter().position(|e| e == c).unwrap() as u8;
             n = n * u128::from(62);
             n = n * u128::from(62);
             n = n + u128::from(d);
             n = n + u128::from(d);
         }
         }
@@ -62,7 +62,7 @@ impl SpotifyId {
             data[15-i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
             data[15-i] = BASE16_DIGITS[(high.wrapping_shr(4 * i as u32) & 0xF) as usize];
         }
         }
 
 
-        std::str::from_utf8(&data).unwrap().to_string()
+        std::str::from_utf8(&data).unwrap().to_owned()
     }
     }
 
 
     pub fn to_raw(&self) -> [u8; 16] {
     pub fn to_raw(&self) -> [u8; 16] {

+ 2 - 2
src/util/zerofile.rs

@@ -33,8 +33,8 @@ impl io::Read for ZeroFile {
     // TODO optimize with memset or similar
     // TODO optimize with memset or similar
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
     fn read(&mut self, output: &mut [u8]) -> io::Result<usize> {
         let len = min(output.len(), (self.size - self.position) as usize);
         let len = min(output.len(), (self.size - self.position) as usize);
-        for i in 0..len {
-            output[i] = 0;
+        for b in output {
+            *b = 0;
         }
         }
 
 
         self.position += len as u64;
         self.position += len as u64;