diff --git a/README.md b/README.md index 7102c28a..33b2b76e 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ ALSA PortAudio PulseAudio JACK -JACK over Rodio +JACK over Rodio SDL Pipe ``` diff --git a/connect/src/discovery.rs b/connect/src/discovery.rs index df4d48eb..7bb36a20 100644 --- a/connect/src/discovery.rs +++ b/connect/src/discovery.rs @@ -13,9 +13,6 @@ use tokio::sync::{mpsc, oneshot}; #[cfg(feature = "with-dns-sd")] use dns_sd::DNSService; -#[cfg(not(feature = "with-dns-sd"))] -use libmdns; - use librespot_core::authentication::Credentials; use librespot_core::config::ConnectConfig; use librespot_core::diffie_hellman::{DH_GENERATOR, DH_PRIME}; @@ -54,11 +51,11 @@ impl Discovery { let public_key = util::powm(&DH_GENERATOR, &private_key, &DH_PRIME); let discovery = Discovery(Arc::new(DiscoveryInner { - config: config, - device_id: device_id, - private_key: private_key, - public_key: public_key, - tx: tx, + config, + device_id, + private_key, + public_key, + tx, })); (discovery, rx) @@ -127,7 +124,7 @@ impl Discovery { let mut h = HmacSha1::new_varkey(&checksum_key).expect("HMAC can take key of any size"); h.update(encrypted); - if let Err(_) = h.verify(cksum) { + if h.verify(cksum).is_err() { warn!("Login error for user {:?}: MAC mismatch", username); let result = json!({ "status": 102, diff --git a/connect/src/spirc.rs b/connect/src/spirc.rs index 5afefe7f..f111e541 100644 --- a/connect/src/spirc.rs +++ b/connect/src/spirc.rs @@ -287,27 +287,27 @@ impl Spirc { let player_events = player.get_player_event_channel(); let mut task = SpircTask { - player: player, - mixer: mixer, + player, + mixer, config: task_config, sequence: SeqGenerator::new(1), - ident: ident, + ident, - device: device, + device, state: initial_state(), play_request_id: None, mixer_started: false, play_status: SpircPlayStatus::Stopped, - subscription: subscription, - sender: sender, + subscription, + sender, commands: Some(cmd_rx), player_events: Some(player_events), shutdown: false, - session: session, + session, context_fut: Box::pin(future::pending()), autoplay_fut: Box::pin(future::pending()), @@ -426,8 +426,8 @@ impl SpircTask { Ok(dur) => dur, Err(err) => err.duration(), }; - (dur.as_secs() as i64 + self.session.time_delta()) * 1000 - + (dur.subsec_nanos() / 1000_000) as i64 + + dur.as_millis() as i64 + 1000 * self.session.time_delta() } fn ensure_mixer_started(&mut self) { @@ -512,7 +512,9 @@ impl SpircTask { SpircCommand::Shutdown => { CommandSender::new(self, MessageType::kMessageTypeGoodbye).send(); self.shutdown = true; - self.commands.as_mut().map(|rx| rx.close()); + if let Some(rx) = self.commands.as_mut() { + rx.close() + } } } } @@ -620,7 +622,7 @@ impl SpircTask { ); if frame.get_ident() == self.ident - || (frame.get_recipient().len() > 0 && !frame.get_recipient().contains(&self.ident)) + || (!frame.get_recipient().is_empty() && !frame.get_recipient().contains(&self.ident)) { return; } @@ -639,7 +641,7 @@ impl SpircTask { self.update_tracks(&frame); - if self.state.get_track().len() > 0 { + if !self.state.get_track().is_empty() { let start_playing = frame.get_state().get_status() == PlayStatus::kPlayStatusPlay; self.load_track(start_playing, frame.get_state().get_position_ms()); @@ -862,7 +864,7 @@ impl SpircTask { fn preview_next_track(&mut self) -> Option { self.get_track_id_to_play_from_playlist(self.state.get_playing_track_index() + 1) - .and_then(|(track_id, _)| Some(track_id)) + .map(|(track_id, _)| track_id) } fn handle_preload_next_track(&mut self) { @@ -981,7 +983,7 @@ impl SpircTask { }; // Reinsert queued tracks after the new playing track. let mut pos = (new_index + 1) as usize; - for track in queue_tracks.into_iter() { + for track in queue_tracks { self.state.mut_track().insert(pos, track); pos += 1; } @@ -1120,7 +1122,7 @@ impl SpircTask { } self.state.set_playing_track_index(index); - self.state.set_track(tracks.into_iter().cloned().collect()); + self.state.set_track(tracks.iter().cloned().collect()); self.state.set_context_uri(context_uri); // has_shuffle/repeat seem to always be true in these replace msgs, // but to replicate the behaviour of the Android client we have to @@ -1291,10 +1293,7 @@ impl<'a> CommandSender<'a> { frame.set_typ(cmd); frame.set_device_state(spirc.device.clone()); frame.set_state_update_id(spirc.now_ms()); - CommandSender { - spirc: spirc, - frame: frame, - } + CommandSender { spirc, frame } } fn recipient(mut self, recipient: &'a str) -> CommandSender { diff --git a/core/src/channel.rs b/core/src/channel.rs index 4e73b616..387b3966 100644 --- a/core/src/channel.rs +++ b/core/src/channel.rs @@ -192,11 +192,12 @@ impl Stream for ChannelData { }; loop { - let x = match channel.poll_next_unpin(cx) { + let event = match channel.poll_next_unpin(cx) { Poll::Ready(x) => x.transpose()?, Poll::Pending => return Poll::Pending, }; - match x { + + match event { Some(ChannelEvent::Header(..)) => (), Some(ChannelEvent::Data(data)) => return Poll::Ready(Some(Ok(data))), None => return Poll::Ready(None), @@ -214,12 +215,12 @@ impl Stream for ChannelHeaders { Poll::Pending => return Poll::Pending, }; - let x = match channel.poll_next_unpin(cx) { + let event = match channel.poll_next_unpin(cx) { Poll::Ready(x) => x.transpose()?, Poll::Pending => return Poll::Pending, }; - match x { + match event { Some(ChannelEvent::Header(id, data)) => Poll::Ready(Some(Ok((id, data)))), Some(ChannelEvent::Data(..)) | None => Poll::Ready(None), } diff --git a/core/src/connection/handshake.rs b/core/src/connection/handshake.rs index 02d77134..67a786ee 100644 --- a/core/src/connection/handshake.rs +++ b/core/src/connection/handshake.rs @@ -104,11 +104,11 @@ where Ok(message) } -async fn read_into_accumulator<'a, T: AsyncRead + Unpin>( - connection: &mut T, +async fn read_into_accumulator<'a, 'b, T: AsyncRead + Unpin>( + connection: &'a mut T, size: usize, - acc: &'a mut Vec, -) -> io::Result<&'a mut [u8]> { + acc: &'b mut Vec, +) -> io::Result<&'b mut [u8]> { let offset = acc.len(); acc.resize(offset + size, 0); diff --git a/metadata/src/lib.rs b/metadata/src/lib.rs index 75c07f83..2c982ec7 100644 --- a/metadata/src/lib.rs +++ b/metadata/src/lib.rs @@ -1,5 +1,4 @@ #![allow(clippy::unused_io_amount)] -#![allow(clippy::redundant_field_names)] #[macro_use] extern crate log; @@ -85,7 +84,7 @@ impl AudioFiles for Track { async fn get_audio_item(session: &Session, id: SpotifyId) -> Result { let item = Self::get(session, id).await?; Ok(AudioItem { - id: id, + id, uri: format!("spotify:track:{}", id.to_base62()), files: item.files, name: item.name, @@ -102,7 +101,7 @@ impl AudioFiles for Episode { let item = Self::get(session, id).await?; Ok(AudioItem { - id: id, + id, uri: format!("spotify:episode:{}", id.to_base62()), files: item.files, name: item.name, @@ -222,8 +221,8 @@ impl Metadata for Track { name: msg.get_name().to_owned(), duration: msg.get_duration(), album: SpotifyId::from_raw(msg.get_album().get_gid()).unwrap(), - artists: artists, - files: files, + artists, + files, alternatives: msg .get_alternative() .iter() @@ -272,9 +271,9 @@ impl Metadata for Album { Album { id: SpotifyId::from_raw(msg.get_gid()).unwrap(), name: msg.get_name().to_owned(), - artists: artists, - tracks: tracks, - covers: covers, + artists, + tracks, + covers, } } } @@ -309,7 +308,7 @@ impl Metadata for Playlist { Playlist { revision: msg.get_revision().to_vec(), name: msg.get_attributes().get_name().to_owned(), - tracks: tracks, + tracks, user: msg.get_owner_username().to_string(), } } @@ -342,7 +341,7 @@ impl Metadata for Artist { Artist { id: SpotifyId::from_raw(msg.get_gid()).unwrap(), name: msg.get_name().to_owned(), - top_tracks: top_tracks, + top_tracks, } } } @@ -388,8 +387,8 @@ impl Metadata for Episode { duration: msg.get_duration().to_owned(), language: msg.get_language().to_owned(), show: SpotifyId::from_raw(msg.get_show().get_gid()).unwrap(), - covers: covers, - files: files, + covers, + files, available: parse_restrictions(msg.get_restriction(), &country, "premium"), explicit: msg.get_explicit().to_owned(), } @@ -427,8 +426,8 @@ impl Metadata for Show { id: SpotifyId::from_raw(msg.get_gid()).unwrap(), name: msg.get_name().to_owned(), publisher: msg.get_publisher().to_owned(), - episodes: episodes, - covers: covers, + episodes, + covers, } } } diff --git a/playback/src/mixer/mod.rs b/playback/src/mixer/mod.rs index 325c1e18..9d9a8175 100644 --- a/playback/src/mixer/mod.rs +++ b/playback/src/mixer/mod.rs @@ -42,11 +42,13 @@ impl Default for MixerConfig { pub mod softmixer; use self::softmixer::SoftMixer; +type MixerFn = fn(Option) -> Box; + fn mk_sink(device: Option) -> Box { Box::new(M::open(device)) } -pub fn find>(name: Option) -> Option) -> Box> { +pub fn find>(name: Option) -> Option { match name.as_ref().map(AsRef::as_ref) { None | Some("softvol") => Some(mk_sink::), #[cfg(feature = "alsa-backend")] diff --git a/playback/src/player.rs b/playback/src/player.rs index 7c200b2a..0d2380e7 100644 --- a/playback/src/player.rs +++ b/playback/src/player.rs @@ -196,19 +196,18 @@ struct NormalisationData { impl NormalisationData { fn parse_from_file(mut file: T) -> io::Result { const SPOTIFY_NORMALIZATION_HEADER_START_OFFSET: u64 = 144; - file.seek(SeekFrom::Start(SPOTIFY_NORMALIZATION_HEADER_START_OFFSET)) - .unwrap(); + file.seek(SeekFrom::Start(SPOTIFY_NORMALIZATION_HEADER_START_OFFSET))?; - let track_gain_db = file.read_f32::().unwrap(); - let track_peak = file.read_f32::().unwrap(); - let album_gain_db = file.read_f32::().unwrap(); - let album_peak = file.read_f32::().unwrap(); + let track_gain_db = file.read_f32::()?; + let track_peak = file.read_f32::()?; + let album_gain_db = file.read_f32::()?; + let album_peak = file.read_f32::()?; let r = NormalisationData { - track_gain_db: track_gain_db, - track_peak: track_peak, - album_gain_db: album_gain_db, - album_peak: album_peak, + track_gain_db, + track_peak, + album_gain_db, + album_peak, }; Ok(r) @@ -889,8 +888,7 @@ impl Future for PlayerInternal { if !passthrough { if let Some(ref packet) = packet { - *stream_position_pcm = - *stream_position_pcm + (packet.samples().len() / 2) as u64; + *stream_position_pcm += (packet.samples().len() / 2) as u64; let stream_position_millis = Self::position_pcm_to_ms(*stream_position_pcm); @@ -1111,7 +1109,9 @@ impl PlayerInternal { editor.modify_stream(data) } - if self.config.normalisation && normalisation_factor != 1.0 { + if self.config.normalisation + && f32::abs(normalisation_factor - 1.0) > f32::EPSILON + { for x in data.iter_mut() { *x = (*x as f32 * normalisation_factor) as i16; } @@ -1164,8 +1164,8 @@ impl PlayerInternal { }); self.state = PlayerState::Playing { - track_id: track_id, - play_request_id: play_request_id, + track_id, + play_request_id, decoder: loaded_track.decoder, normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, @@ -1181,8 +1181,8 @@ impl PlayerInternal { self.ensure_sink_stopped(false); self.state = PlayerState::Paused { - track_id: track_id, - play_request_id: play_request_id, + track_id, + play_request_id, decoder: loaded_track.decoder, normalisation_factor: loaded_track.normalisation_factor, stream_loader_controller: loaded_track.stream_loader_controller, @@ -1229,7 +1229,7 @@ impl PlayerInternal { track_id: old_track_id, .. } => self.send_event(PlayerEvent::Changed { - old_track_id: old_track_id, + old_track_id, new_track_id: track_id, }), PlayerState::Stopped => self.send_event(PlayerEvent::Started { @@ -1598,12 +1598,10 @@ impl PlayerInternal { let (result_tx, result_rx) = oneshot::channel(); std::thread::spawn(move || { - futures_executor::block_on(loader.load_track(spotify_id, position_ms)).and_then( - move |data| { - let _ = result_tx.send(data); - Some(()) - }, - ); + let data = futures_executor::block_on(loader.load_track(spotify_id, position_ms)); + if let Some(data) = data { + let _ = result_tx.send(data); + } }); result_rx.map_err(|_| ()) @@ -1728,10 +1726,7 @@ struct Subfile { impl Subfile { pub fn new(mut stream: T, offset: u64) -> Subfile { stream.seek(SeekFrom::Start(offset)).unwrap(); - Subfile { - stream: stream, - offset: offset, - } + Subfile { stream, offset } } } diff --git a/src/main.rs b/src/main.rs index 6f04ac1f..5b445b2c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -236,13 +236,7 @@ fn setup(args: &[String]) -> Setup { let matches = match opts.parse(&args[1..]) { Ok(m) => m, Err(f) => { - writeln!( - stderr(), - "error: {}\n{}", - f.to_string(), - usage(&args[0], &opts) - ) - .unwrap(); + eprintln!("error: {}\n{}", f.to_string(), usage(&args[0], &opts)); exit(1); } }; @@ -359,8 +353,8 @@ fn setup(args: &[String]) -> Setup { SessionConfig { user_agent: version::version_string(), - device_id: device_id, - proxy: matches.opt_str("proxy").or(std::env::var("http_proxy").ok()).map( + device_id, + proxy: matches.opt_str("proxy").or_else(|| std::env::var("http_proxy").ok()).map( |s| { match Url::parse(&s) { Ok(url) => { @@ -390,16 +384,16 @@ fn setup(args: &[String]) -> Setup { .opt_str("b") .as_ref() .map(|bitrate| Bitrate::from_str(bitrate).expect("Invalid bitrate")) - .unwrap_or(Bitrate::default()); + .unwrap_or_default(); let gain_type = matches .opt_str("normalisation-gain-type") .as_ref() .map(|gain_type| { NormalisationType::from_str(gain_type).expect("Invalid normalisation type") }) - .unwrap_or(NormalisationType::default()); + .unwrap_or_default(); PlayerConfig { - bitrate: bitrate, + bitrate, gapless: !matches.opt_present("disable-gapless"), normalisation: matches.opt_present("enable-volume-normalisation"), normalisation_type: gain_type, @@ -416,19 +410,19 @@ fn setup(args: &[String]) -> Setup { .opt_str("device-type") .as_ref() .map(|device_type| DeviceType::from_str(device_type).expect("Invalid device type")) - .unwrap_or(DeviceType::default()); + .unwrap_or_default(); let volume_ctrl = matches .opt_str("volume-ctrl") .as_ref() .map(|volume_ctrl| VolumeCtrl::from_str(volume_ctrl).expect("Invalid volume ctrl type")) - .unwrap_or(VolumeCtrl::default()); + .unwrap_or_default(); ConnectConfig { - name: name, - device_type: device_type, + name, + device_type, volume: initial_volume, - volume_ctrl: volume_ctrl, + volume_ctrl, autoplay: matches.opt_present("autoplay"), } }; @@ -436,17 +430,17 @@ fn setup(args: &[String]) -> Setup { let enable_discovery = !matches.opt_present("disable-discovery"); Setup { - backend: backend, - cache: cache, - session_config: session_config, - player_config: player_config, - connect_config: connect_config, - credentials: credentials, - device: device, - enable_discovery: enable_discovery, - zeroconf_port: zeroconf_port, - mixer: mixer, - mixer_config: mixer_config, + backend, + cache, + session_config, + player_config, + connect_config, + credentials, + device, + enable_discovery, + zeroconf_port, + mixer, + mixer_config, player_event_program: matches.opt_str("onevent"), emit_sink_events: matches.opt_present("emit-sink-events"), }