1
0
Fork 0
mirror of https://github.com/librespot-org/librespot.git synced 2025-10-02 17:29:22 +02:00

style: format with style edition 2024

This commit is contained in:
Roderick van Domburg 2025-08-13 23:09:59 +02:00
parent 056d125cb2
commit 218eced556
No known key found for this signature in database
GPG key ID: 607FA06CB5236AE0
62 changed files with 196 additions and 139 deletions

View file

@ -5,21 +5,21 @@ use std::{
fs,
io::{self, Read, Seek, SeekFrom},
sync::{
atomic::{AtomicBool, AtomicUsize, Ordering},
Arc, OnceLock,
atomic::{AtomicBool, AtomicUsize, Ordering},
},
time::Duration,
};
use futures_util::{future::IntoStream, StreamExt, TryFutureExt};
use hyper::{body::Incoming, header::CONTENT_RANGE, Response, StatusCode};
use futures_util::{StreamExt, TryFutureExt, future::IntoStream};
use hyper::{Response, StatusCode, body::Incoming, header::CONTENT_RANGE};
use hyper_util::client::legacy::ResponseFuture;
use parking_lot::{Condvar, Mutex};
use tempfile::NamedTempFile;
use thiserror::Error;
use tokio::sync::{mpsc, oneshot, Semaphore};
use tokio::sync::{Semaphore, mpsc, oneshot};
use librespot_core::{cdn_url::CdnUrl, Error, FileId, Session};
use librespot_core::{Error, FileId, Session, cdn_url::CdnUrl};
use self::receive::audio_file_fetch;

View file

@ -12,7 +12,7 @@ use hyper::StatusCode;
use tempfile::NamedTempFile;
use tokio::sync::{mpsc, oneshot};
use librespot_core::{http_client::HttpClient, session::Session, Error};
use librespot_core::{Error, http_client::HttpClient, session::Session};
use crate::range_set::{Range, RangeSet};

View file

@ -4,7 +4,7 @@ use crate::{
autoplay_context_request::AutoplayContextRequest, context::Context,
transfer_state::TransferState,
},
state::{context::ContextType, ConnectState},
state::{ConnectState, context::ContextType},
};
use std::{
cmp::PartialEq,

View file

@ -1,4 +1,4 @@
use rand::{rngs::SmallRng, Rng, SeedableRng};
use rand::{Rng, SeedableRng, rngs::SmallRng};
use std::{
ops::{Deref, DerefMut},
vec::IntoIter,

View file

@ -1,13 +1,14 @@
use crate::{
LoadContextOptions, LoadRequestOptions, PlayContext,
context_resolver::{ContextAction, ContextResolver, ResolveContext},
core::{
Error, Session, SpotifyId,
authentication::Credentials,
dealer::{
manager::{BoxedStream, BoxedStreamResult, Reply, RequestReply},
protocol::{Command, FallbackWrapper, Message, Request},
},
session::UserAttributes,
Error, Session, SpotifyId,
},
model::{LoadRequest, PlayingTrack, SpircPlayStatus},
playback::{
@ -28,15 +29,14 @@ use crate::{
provider::IsProvider,
{ConnectConfig, ConnectState},
},
LoadContextOptions, LoadRequestOptions, PlayContext,
};
use futures_util::StreamExt;
use librespot_protocol::context_page::ContextPage;
use protobuf::MessageField;
use std::{
future::Future,
sync::atomic::{AtomicUsize, Ordering},
sync::Arc,
sync::atomic::{AtomicUsize, Ordering},
time::{Duration, SystemTime, UNIX_EPOCH},
};
use thiserror::Error;
@ -951,7 +951,8 @@ impl SpircTask {
{
debug!(
"ignoring context update for <{:?}>, because it isn't the current context <{}>",
update_context.context.uri, self.connect_state.context_uri()
update_context.context.uri,
self.connect_state.context_uri()
)
} else {
self.context_resolver.add(ResolveContext::from_context(
@ -1615,7 +1616,9 @@ impl SpircTask {
let uri = String::from_utf8(uri)?;
if self.connect_state.context_uri() != &uri {
debug!("ignoring playlist modification update for playlist <{uri}>, because it isn't the current context");
debug!(
"ignoring playlist modification update for playlist <{uri}>, because it isn't the current context"
);
return Ok(());
}

View file

@ -9,8 +9,8 @@ mod transfer;
use crate::{
core::{
config::DeviceType, date::Date, dealer::protocol::Request, spclient::SpClientResult,
version, Error, Session,
Error, Session, config::DeviceType, date::Date, dealer::protocol::Request,
spclient::SpClientResult, version,
},
model::SpircPlayStatus,
protocol::{

View file

@ -9,9 +9,9 @@ use crate::{
},
shuffle_vec::ShuffleVec,
state::{
ConnectState, SPOTIFY_MAX_NEXT_TRACKS_SIZE, StateError,
metadata::Metadata,
provider::{IsProvider, Provider},
ConnectState, StateError, SPOTIFY_MAX_NEXT_TRACKS_SIZE,
},
};
use protobuf::MessageField;

View file

@ -1,9 +1,9 @@
use crate::{
core::{dealer::protocol::SetQueueCommand, Error},
core::{Error, dealer::protocol::SetQueueCommand},
state::{
ConnectState,
context::{ContextType, ResetContext},
metadata::Metadata,
ConnectState,
},
};
use protobuf::MessageField;

View file

@ -2,9 +2,9 @@ use crate::{
core::Error,
protocol::player::ContextPlayerOptions,
state::{
ConnectState, StateError,
context::{ContextType, ResetContext},
metadata::Metadata,
ConnectState, StateError,
},
};
use protobuf::MessageField;

View file

@ -1,5 +1,5 @@
use crate::state::provider::IsProvider;
use crate::state::ConnectState;
use crate::state::provider::IsProvider;
use librespot_protocol::player::Restrictions;
use protobuf::MessageField;

View file

@ -2,10 +2,10 @@ use crate::{
core::{Error, SpotifyId},
protocol::player::ProvidedTrack,
state::{
ConnectState, SPOTIFY_MAX_NEXT_TRACKS_SIZE, SPOTIFY_MAX_PREV_TRACKS_SIZE, StateError,
context::ContextType,
metadata::Metadata,
provider::{IsProvider, Provider},
ConnectState, StateError, SPOTIFY_MAX_NEXT_TRACKS_SIZE, SPOTIFY_MAX_PREV_TRACKS_SIZE,
},
};
use protobuf::MessageField;

View file

@ -139,7 +139,7 @@ impl ApResolver {
_ => {
return Err(Error::unimplemented(format!(
"No implementation to resolve access point {endpoint}"
)))
)));
}
};

View file

@ -5,7 +5,7 @@ use bytes::Bytes;
use thiserror::Error;
use tokio::sync::oneshot;
use crate::{packet::PacketType, util::SeqGenerator, Error, FileId, SpotifyId};
use crate::{Error, FileId, SpotifyId, packet::PacketType, util::SeqGenerator};
#[derive(Debug, Hash, PartialEq, Eq, Copy, Clone)]
pub struct AudioKey(pub [u8; 16]);

View file

@ -1,8 +1,8 @@
use std::io::{self, Read};
use aes::Aes192;
use base64::engine::general_purpose::STANDARD as BASE64;
use base64::engine::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64;
use byteorder::{BigEndian, ByteOrder};
use pbkdf2::pbkdf2_hmac;
use protobuf::Enum;
@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize};
use sha1::{Digest, Sha1};
use thiserror::Error;
use crate::{protocol::authentication::AuthenticationType, Error};
use crate::{Error, protocol::authentication::AuthenticationType};
#[derive(Debug, Error)]
pub enum AuthenticationError {

View file

@ -12,7 +12,7 @@ use parking_lot::Mutex;
use priority_queue::PriorityQueue;
use thiserror::Error;
use crate::{authentication::Credentials, error::ErrorKind, Error, FileId};
use crate::{Error, FileId, authentication::Credentials, error::ErrorKind};
#[derive(Debug, Error)]
pub enum CacheError {

View file

@ -5,11 +5,11 @@ use thiserror::Error;
use time::Duration;
use url::Url;
use super::{date::Date, Error, FileId, Session};
use super::{Error, FileId, Session, date::Date};
use librespot_protocol as protocol;
use protocol::storage_resolve::storage_resolve_response::Result as StorageResolveResponse_Result;
use protocol::storage_resolve::StorageResolveResponse as CdnUrlMessage;
use protocol::storage_resolve::storage_resolve_response::Result as StorageResolveResponse_Result;
#[derive(Debug, Clone)]
pub struct MaybeExpiringUrl(pub String, pub Option<Date>);
@ -201,7 +201,9 @@ impl TryFrom<CdnUrlMessage> for MaybeExpiringUrls {
expiry = Some(Date::from(with_margin));
}
} else {
warn!("Cannot parse CDN URL expiry timestamp '{exp_str}' from '{cdn_url}'");
warn!(
"Cannot parse CDN URL expiry timestamp '{exp_str}' from '{cdn_url}'"
);
}
} else {
warn!("Unknown CDN URL format: {cdn_url}");
@ -225,10 +227,18 @@ mod test {
let mut msg = CdnUrlMessage::new();
msg.result = StorageResolveResponse_Result::CDN.into();
msg.cdnurl = vec![
format!("https://audio-cf.spotifycdn.com/audio/844ecdb297a87ebfee4399f28892ef85d9ba725f?verify={timestamp}-4R3I2w2q7OfNkR%2FGH8qH7xtIKUPlDxywBuADY%2BsvMeU%3D"),
format!("https://audio-ak-spotify-com.akamaized.net/audio/foo?__token__=exp={timestamp}~hmac=4e661527574fab5793adb99cf04e1c2ce12294c71fe1d39ffbfabdcfe8ce3b41"),
format!("https://audio-gm-off.spotifycdn.com/audio/foo?Expires={timestamp}~FullPath~hmac=IIZA28qptl8cuGLq15-SjHKHtLoxzpy_6r_JpAU4MfM="),
format!("https://audio4-fa.scdn.co/audio/foo?{timestamp}_0GKSyXjLaTW1BksFOyI4J7Tf9tZDbBUNNPu9Mt4mhH4="),
format!(
"https://audio-cf.spotifycdn.com/audio/844ecdb297a87ebfee4399f28892ef85d9ba725f?verify={timestamp}-4R3I2w2q7OfNkR%2FGH8qH7xtIKUPlDxywBuADY%2BsvMeU%3D"
),
format!(
"https://audio-ak-spotify-com.akamaized.net/audio/foo?__token__=exp={timestamp}~hmac=4e661527574fab5793adb99cf04e1c2ce12294c71fe1d39ffbfabdcfe8ce3b41"
),
format!(
"https://audio-gm-off.spotifycdn.com/audio/foo?Expires={timestamp}~FullPath~hmac=IIZA28qptl8cuGLq15-SjHKHtLoxzpy_6r_JpAU4MfM="
),
format!(
"https://audio4-fa.scdn.co/audio/foo?{timestamp}_0GKSyXjLaTW1BksFOyI4J7Tf9tZDbBUNNPu9Mt4mhH4="
),
"https://audio4-fa.scdn.co/foo?baz".to_string(),
];
msg.fileid = vec![0];

View file

@ -9,12 +9,12 @@ use std::{
use byteorder::{BigEndian, ByteOrder};
use bytes::Bytes;
use futures_core::Stream;
use futures_util::{lock::BiLock, ready, StreamExt};
use futures_util::{StreamExt, lock::BiLock, ready};
use num_traits::FromPrimitive;
use thiserror::Error;
use tokio::sync::mpsc;
use crate::{packet::PacketType, util::SeqGenerator, Error};
use crate::{Error, packet::PacketType, util::SeqGenerator};
component! {
ChannelManager : ChannelManagerInner {

View file

@ -13,7 +13,7 @@ use tokio::net::TcpStream;
use tokio_util::codec::Framed;
use url::Url;
use crate::{authentication::Credentials, packet::PacketType, version, Error};
use crate::{Error, authentication::Credentials, packet::PacketType, version};
use crate::protocol::keyexchange::{APLoginFailed, ErrorCode};

View file

@ -1,8 +1,8 @@
use std::{fmt::Debug, ops::Deref};
use time::{
error::ComponentRange, format_description::well_known::Iso8601, Date as _Date, OffsetDateTime,
PrimitiveDateTime, Time,
Date as _Date, OffsetDateTime, PrimitiveDateTime, Time, error::ComponentRange,
format_description::well_known::Iso8601,
};
use crate::Error;

View file

@ -7,8 +7,8 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
use url::Url;
use super::{
protocol::Message, Builder, Dealer, GetUrlResult, Request, RequestHandler, Responder, Response,
Subscription,
Builder, Dealer, GetUrlResult, Request, RequestHandler, Responder, Response, Subscription,
protocol::Message,
};
use crate::{Error, Session};

View file

@ -6,22 +6,22 @@ use std::{
iter,
pin::Pin,
sync::{
atomic::{self, AtomicBool},
Arc,
atomic::{self, AtomicBool},
},
task::Poll,
time::Duration,
};
use futures_core::{Future, Stream};
use futures_util::{future::join_all, SinkExt, StreamExt};
use futures_util::{SinkExt, StreamExt, future::join_all};
use parking_lot::Mutex;
use thiserror::Error;
use tokio::{
select,
sync::{
mpsc::{self, UnboundedReceiver},
Semaphore,
mpsc::{self, UnboundedReceiver},
},
task::JoinHandle,
};
@ -35,9 +35,8 @@ use self::{
};
use crate::{
socket,
util::{keep_flushing, CancelOnDrop, TimeoutOnDrop},
Error,
Error, socket,
util::{CancelOnDrop, TimeoutOnDrop, keep_flushing},
};
type WsMessage = tungstenite::Message;

View file

@ -5,8 +5,8 @@ pub use request::*;
use std::collections::HashMap;
use std::io::{Error as IoError, Read};
use crate::{deserialize_with::json_proto, Error};
use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};
use crate::{Error, deserialize_with::json_proto};
use base64::{DecodeError, Engine, prelude::BASE64_STANDARD};
use flate2::read::GzDecoder;
use log::LevelFilter;
use serde::Deserialize;

View file

@ -1,5 +1,5 @@
use base64::prelude::BASE64_STANDARD;
use base64::Engine;
use base64::prelude::BASE64_STANDARD;
use protobuf::MessageFull;
use serde::de::{Error, Unexpected};
use serde::{Deserialize, Deserializer};

View file

@ -15,7 +15,7 @@ use http::{
use protobuf::Error as ProtobufError;
use thiserror::Error;
use tokio::sync::{
mpsc::error::SendError, oneshot::error::RecvError, AcquireError, TryAcquireError,
AcquireError, TryAcquireError, mpsc::error::SendError, oneshot::error::RecvError,
};
use url::ParseError;

View file

@ -2,7 +2,7 @@ use std::fmt;
use librespot_protocol as protocol;
use crate::{spotify_id::to_base16, Error};
use crate::{Error, spotify_id::to_base16};
const RAW_LEN: usize = 20;

View file

@ -5,17 +5,17 @@ use std::{
};
use bytes::Bytes;
use futures_util::{future::IntoStream, FutureExt};
use futures_util::{FutureExt, future::IntoStream};
use governor::{
clock::MonotonicClock, middleware::NoOpMiddleware, state::InMemoryState, Quota, RateLimiter,
Quota, RateLimiter, clock::MonotonicClock, middleware::NoOpMiddleware, state::InMemoryState,
};
use http::{header::HeaderValue, Uri};
use http::{Uri, header::HeaderValue};
use http_body_util::{BodyExt, Full};
use hyper::{body::Incoming, header::USER_AGENT, HeaderMap, Request, Response, StatusCode};
use hyper::{HeaderMap, Request, Response, StatusCode, body::Incoming, header::USER_AGENT};
use hyper_proxy2::{Intercept, Proxy, ProxyConnector};
use hyper_rustls::{HttpsConnector, HttpsConnectorBuilder};
use hyper_util::{
client::legacy::{connect::HttpConnector, Client, ResponseFuture},
client::legacy::{Client, ResponseFuture, connect::HttpConnector},
rt::TokioExecutor,
};
use nonzero_ext::nonzero;
@ -24,10 +24,10 @@ use thiserror::Error;
use url::Url;
use crate::{
config::{os_version, OS},
date::Date,
version::{spotify_version, FALLBACK_USER_AGENT, VERSION_STRING},
Error,
config::{OS, os_version},
date::Date,
version::{FALLBACK_USER_AGENT, VERSION_STRING, spotify_version},
};
// The 30 seconds interval is documented by Spotify, but the calls per interval

View file

@ -1,17 +1,17 @@
use crate::config::OS;
use crate::spclient::CLIENT_TOKEN;
use crate::token::Token;
use crate::{util, Error, SessionConfig};
use crate::{Error, SessionConfig, util};
use bytes::Bytes;
use http::{header::ACCEPT, HeaderValue, Method, Request};
use http::{HeaderValue, Method, Request, header::ACCEPT};
use librespot_protocol::login5::login_response::Response;
use librespot_protocol::{
client_info::ClientInfo,
credentials::{Password, StoredCredential},
hashcash::HashcashSolution,
login5::{
login_request::Login_method, ChallengeSolution, LoginError, LoginOk, LoginRequest,
LoginResponse,
ChallengeSolution, LoginError, LoginOk, LoginRequest, LoginResponse,
login_request::Login_method,
},
};
use protobuf::well_known_types::duration::Duration as ProtoDuration;

View file

@ -11,7 +11,7 @@ use futures_util::FutureExt;
use protobuf::Message;
use tokio::sync::{mpsc, oneshot};
use crate::{packet::PacketType, protocol, util::SeqGenerator, Error};
use crate::{Error, packet::PacketType, protocol, util::SeqGenerator};
mod types;
pub use self::types::*;

View file

@ -4,7 +4,7 @@ use byteorder::{BigEndian, WriteBytesExt};
use protobuf::Message;
use thiserror::Error;
use crate::{packet::PacketType, protocol, Error};
use crate::{Error, packet::PacketType, protocol};
#[derive(Debug, PartialEq, Eq)]
pub enum MercuryMethod {

View file

@ -12,6 +12,7 @@ use std::{
use crate::dealer::manager::DealerManager;
use crate::{
Error,
apresolve::{ApResolver, SocketAddress},
audio_key::AudioKeyManager,
authentication::Credentials,
@ -26,7 +27,6 @@ use crate::{
protocol::keyexchange::ErrorCode,
spclient::SpClient,
token::TokenProvider,
Error,
};
use byteorder::{BigEndian, ByteOrder};
use bytes::Bytes;
@ -40,7 +40,7 @@ use quick_xml::events::Event;
use thiserror::Error;
use tokio::{
sync::mpsc,
time::{sleep, Duration as TokioDuration, Instant as TokioInstant, Sleep},
time::{Duration as TokioDuration, Instant as TokioInstant, Sleep, sleep},
};
use tokio_stream::wrappers::UnboundedReceiverStream;
use uuid::Uuid;

View file

@ -3,8 +3,9 @@ use std::{
time::{Duration, Instant},
};
use crate::config::{os_version, OS};
use crate::config::{OS, os_version};
use crate::{
Error, FileId, SpotifyId,
apresolve::SocketAddress,
config::SessionConfig,
error::ErrorKind,
@ -21,15 +22,14 @@ use crate::{
token::Token,
util,
version::spotify_semantic_version,
Error, FileId, SpotifyId,
};
use bytes::Bytes;
use data_encoding::HEXUPPER_PERMISSIVE;
use futures_util::future::IntoStream;
use http::{header::HeaderValue, Uri};
use http::{Uri, header::HeaderValue};
use hyper::{
header::{HeaderName, ACCEPT, AUTHORIZATION, CONTENT_TYPE, RANGE},
HeaderMap, Method, Request,
header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE, HeaderName, RANGE},
};
use hyper_util::client::legacy::ResponseFuture;
use protobuf::{Enum, Message, MessageFull};
@ -335,7 +335,7 @@ impl SpClient {
Some(unknown) => {
return Err(Error::unimplemented(format!(
"Unknown client token response type: {unknown:?}"
)))
)));
}
None => return Err(Error::failed_precondition("No client token response type")),
}
@ -892,7 +892,9 @@ impl SpClient {
pub async fn get_rootlist(&self, from: usize, length: Option<usize>) -> SpClientResult {
let length = length.unwrap_or(120);
let user = self.session().username();
let endpoint = format!("/playlist/v2/user/{user}/rootlist?decorate=revision,attributes,length,owner,capabilities,status_code&from={from}&length={length}");
let endpoint = format!(
"/playlist/v2/user/{user}/rootlist?decorate=revision,attributes,length,owner,capabilities,status_code&from={from}&length={length}"
);
self.request(&Method::GET, &endpoint, None, None).await
}

View file

@ -1,7 +1,7 @@
use crate::Error;
use byteorder::{BigEndian, ByteOrder};
use futures_core::ready;
use futures_util::{future, FutureExt, Sink, SinkExt};
use futures_util::{FutureExt, Sink, SinkExt, future};
use hmac::digest::Digest;
use sha1::Sha1;
use std::time::{Duration, Instant};
@ -62,11 +62,12 @@ impl<T: Send + 'static> Future for TimeoutOnDrop<T> {
type Output = <JoinHandle<T> as Future>::Output;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let r = ready!(self
.handle
.as_mut()
.expect("Polled after ready")
.poll_unpin(cx));
let r = ready!(
self.handle
.as_mut()
.expect("Polled after ready")
.poll_unpin(cx)
);
self.handle = None;
Poll::Ready(r)
}

View file

@ -211,7 +211,9 @@ async fn avahi_task(
break 'wait_avahi;
}
}
log::warn!("Failed to connect to Avahi, zeroconf discovery will not work until avahi-daemon is started. Check that it is installed and running");
log::warn!(
"Failed to connect to Avahi, zeroconf discovery will not work until avahi-daemon is started. Check that it is installed and running"
);
// If it didn't, wait for the signal
match stream.next().await {

View file

@ -6,13 +6,13 @@ use std::{
};
use aes::cipher::{KeyIvInit, StreamCipher};
use base64::engine::general_purpose::STANDARD as BASE64;
use base64::engine::Engine as _;
use base64::engine::general_purpose::STANDARD as BASE64;
use bytes::Bytes;
use futures_util::{FutureExt, TryFutureExt};
use hmac::{Hmac, Mac};
use http_body_util::{BodyExt, Full};
use hyper::{body::Incoming, Method, Request, Response, StatusCode};
use hyper::{Method, Request, Response, StatusCode, body::Incoming};
use hyper_util::{rt::TokioIo, server::graceful::GracefulShutdown};
use log::{debug, error, warn};
@ -24,7 +24,7 @@ use super::{DiscoveryError, DiscoveryEvent};
use crate::{
core::config::DeviceType,
core::{authentication::Credentials, diffie_hellman::DhLocalKeys, Error},
core::{Error, authentication::Credentials, diffie_hellman::DhLocalKeys},
};
type Aes128Ctr = ctr::Ctr128BE<aes::Aes128>;

View file

@ -4,6 +4,7 @@ use std::{
};
use crate::{
Metadata,
artist::Artists,
availability::Availabilities,
copyright::Copyrights,
@ -14,14 +15,13 @@ use crate::{
sale_period::SalePeriods,
track::Tracks,
util::{impl_deref_wrapped, impl_try_from_repeated},
Metadata,
};
use librespot_core::{date::Date, Error, Session, SpotifyId};
use librespot_core::{Error, Session, SpotifyId, date::Date};
use librespot_protocol as protocol;
pub use protocol::metadata::album::Type as AlbumType;
use protocol::metadata::Disc as DiscMessage;
pub use protocol::metadata::album::Type as AlbumType;
#[derive(Debug, Clone)]
pub struct Album {

View file

@ -4,6 +4,7 @@ use std::{
};
use crate::{
Metadata,
album::Albums,
availability::Availabilities,
external_id::ExternalIds,
@ -13,7 +14,6 @@ use crate::{
sale_period::SalePeriods,
track::Tracks,
util::{impl_deref_wrapped, impl_from_repeated, impl_try_from_repeated},
Metadata,
};
use librespot_core::{Error, Session, SpotifyId};
@ -294,7 +294,7 @@ impl TryFrom<&ActivityPeriodMessage> for ActivityPeriod {
_ => {
return Err(librespot_core::Error::failed_precondition(
"ActivityPeriod is expected to be either a decade or timespan",
))
));
}
};
Ok(activity_period)

View file

@ -1,6 +1,7 @@
use std::fmt::Debug;
use crate::{
Metadata,
artist::ArtistsWithRole,
availability::{AudioItemAvailability, Availabilities, UnavailabilityReason},
episode::Episode,
@ -8,13 +9,12 @@ use crate::{
image::{ImageSize, Images},
restriction::Restrictions,
track::{Track, Tracks},
Metadata,
};
use super::file::AudioFiles;
use librespot_core::{
date::Date, session::UserData, spotify_id::SpotifyItemType, Error, Session, SpotifyId,
Error, Session, SpotifyId, date::Date, session::UserData, spotify_id::SpotifyItemType,
};
pub type AudioItemResult = Result<AudioItem, Error>;

View file

@ -6,8 +6,8 @@ use std::{
use crate::util::{impl_deref_wrapped, impl_from_repeated};
use librespot_protocol as protocol;
pub use protocol::metadata::copyright::Type as CopyrightType;
use protocol::metadata::Copyright as CopyrightMessage;
pub use protocol::metadata::copyright::Type as CopyrightType;
#[derive(Debug, Clone)]
pub struct Copyright {

View file

@ -4,6 +4,7 @@ use std::{
};
use crate::{
Metadata,
audio::file::AudioFiles,
availability::Availabilities,
content_rating::ContentRatings,
@ -12,10 +13,9 @@ use crate::{
restriction::Restrictions,
util::{impl_deref_wrapped, impl_try_from_repeated},
video::VideoFiles,
Metadata,
};
use librespot_core::{date::Date, Error, Session, SpotifyId};
use librespot_core::{Error, Session, SpotifyId, date::Date};
use librespot_protocol as protocol;
pub use protocol::metadata::episode::EpisodeType;

View file

@ -8,11 +8,11 @@ use crate::util::{impl_deref_wrapped, impl_from_repeated, impl_try_from_repeated
use librespot_core::{FileId, SpotifyId};
use librespot_protocol as protocol;
pub use protocol::metadata::image::Size as ImageSize;
use protocol::metadata::Image as ImageMessage;
use protocol::metadata::ImageGroup;
use protocol::playlist4_external::PictureSize as PictureSizeMessage;
pub use protocol::metadata::image::Size as ImageSize;
use protocol::playlist_annotate3::TranscodedPicture as TranscodedPictureMessage;
use protocol::playlist4_external::PictureSize as PictureSizeMessage;
#[derive(Debug, Clone)]
pub struct Image {

View file

@ -3,9 +3,9 @@ use std::fmt::Debug;
use protobuf::Message;
use crate::{
Metadata,
image::TranscodedPictures,
request::{MercuryRequest, RequestResult},
Metadata,
};
use librespot_core::{Error, Session, SpotifyId};

View file

@ -10,7 +10,7 @@ use super::{
permission::Capabilities,
};
use librespot_core::{date::Date, SpotifyId};
use librespot_core::{SpotifyId, date::Date};
use librespot_protocol as protocol;
use protocol::playlist4_external::Item as PlaylistItemMessage;

View file

@ -4,9 +4,9 @@ use std::{
};
use crate::{
Metadata,
request::RequestResult,
util::{impl_deref_wrapped, impl_from_repeated_copy, impl_try_from_repeated},
Metadata,
};
use super::{
@ -15,9 +15,9 @@ use super::{
};
use librespot_core::{
Error, Session,
date::Date,
spotify_id::{NamedSpotifyId, SpotifyId},
Error, Session,
};
use librespot_protocol as protocol;

View file

@ -12,11 +12,11 @@ use crate::{
};
use librespot_protocol as protocol;
pub use protocol::playlist4_external::op::Kind as PlaylistOperationKind;
use protocol::playlist4_external::Add as PlaylistAddMessage;
use protocol::playlist4_external::Mov as PlaylistMoveMessage;
use protocol::playlist4_external::Op as PlaylistOperationMessage;
use protocol::playlist4_external::Rem as PlaylistRemoveMessage;
pub use protocol::playlist4_external::op::Kind as PlaylistOperationKind;
#[derive(Debug, Clone)]
pub struct PlaylistOperation {

View file

@ -1,8 +1,8 @@
use std::fmt::Debug;
use crate::{
availability::Availabilities, copyright::Copyrights, episode::Episodes, image::Images,
restriction::Restrictions, Metadata, RequestResult,
Metadata, RequestResult, availability::Availabilities, copyright::Copyrights,
episode::Episodes, image::Images, restriction::Restrictions,
};
use librespot_core::{Error, Session, SpotifyId};

View file

@ -6,6 +6,7 @@ use std::{
use uuid::Uuid;
use crate::{
Album, Metadata, RequestResult,
artist::{Artists, ArtistsWithRole},
audio::file::AudioFiles,
availability::Availabilities,
@ -14,10 +15,9 @@ use crate::{
restriction::Restrictions,
sale_period::SalePeriods,
util::{impl_deref_wrapped, impl_try_from_repeated},
Album, Metadata, RequestResult,
};
use librespot_core::{date::Date, Error, Session, SpotifyId};
use librespot_core::{Error, Session, SpotifyId, date::Date};
use librespot_protocol as protocol;
#[derive(Debug, Clone)]

View file

@ -14,8 +14,8 @@
use log::{error, info, trace};
use oauth2::basic::BasicTokenType;
use oauth2::{
basic::BasicClient, AuthUrl, AuthorizationCode, ClientId, CsrfToken, EndpointNotSet,
EndpointSet, PkceCodeChallenge, RedirectUrl, Scope, TokenResponse, TokenUrl,
AuthUrl, AuthorizationCode, ClientId, CsrfToken, EndpointNotSet, EndpointSet,
PkceCodeChallenge, RedirectUrl, Scope, TokenResponse, TokenUrl, basic::BasicClient,
};
use oauth2::{EmptyExtraTokenFields, PkceCodeVerifier, RefreshToken, StandardTokenResponse};
use std::io;

View file

@ -262,7 +262,9 @@ fn open_device(dev_name: &str, format: AudioFormat) -> SinkResult<(PCM, usize)>
}
}
} else {
trace!("The device's min reported Buffer size was greater than or equal to its max reported Buffer size.");
trace!(
"The device's min reported Buffer size was greater than or equal to its max reported Buffer size."
);
ZERO_FRAMES
};
@ -320,8 +322,12 @@ fn open_device(dev_name: &str, format: AudioFormat) -> SinkResult<(PCM, usize)>
}
}
} else {
trace!("The device's min reported Period size was greater than or equal to its max reported Period size,");
trace!("or the desired min Period size was greater than or equal to the desired max Period size.");
trace!(
"The device's min reported Period size was greater than or equal to its max reported Period size,"
);
trace!(
"or the desired min Period size was greater than or equal to the desired max Period size."
);
ZERO_FRAMES
};

View file

@ -1,7 +1,7 @@
use gstreamer::{
State,
event::{FlushStart, FlushStop},
prelude::*,
State,
};
use gstreamer as gst;
@ -14,7 +14,7 @@ use std::sync::Arc;
use super::{Open, Sink, SinkAsBytes, SinkError, SinkResult};
use crate::{
config::AudioFormat, convert::Converter, decoder::AudioPacket, NUM_CHANNELS, SAMPLE_RATE,
NUM_CHANNELS, SAMPLE_RATE, config::AudioFormat, convert::Converter, decoder::AudioPacket,
};
pub struct GstreamerSink {

View file

@ -1,12 +1,12 @@
use super::{Open, Sink, SinkError, SinkResult};
use crate::NUM_CHANNELS;
use crate::config::AudioFormat;
use crate::convert::Converter;
use crate::decoder::AudioPacket;
use crate::NUM_CHANNELS;
use jack::{
AsyncClient, AudioOut, Client, ClientOptions, Control, Port, ProcessHandler, ProcessScope,
};
use std::sync::mpsc::{sync_channel, Receiver, SyncSender};
use std::sync::mpsc::{Receiver, SyncSender, sync_channel};
pub struct JackSink {
send: SyncSender<f32>,

View file

@ -44,7 +44,9 @@ pub struct StdoutSink {
impl Open for StdoutSink {
fn open(file: Option<String>, format: AudioFormat) -> Self {
if let Some("?") = file.as_deref() {
println!("\nUsage:\n\nOutput to stdout:\n\n\t--backend pipe\n\nOutput to file:\n\n\t--backend pipe --device {{filename}}\n");
println!(
"\nUsage:\n\nOutput to stdout:\n\n\t--backend pipe\n\nOutput to file:\n\n\t--backend pipe --device {{filename}}\n"
);
exit(0);
}

View file

@ -3,7 +3,7 @@ use crate::config::AudioFormat;
use crate::convert::Converter;
use crate::decoder::AudioPacket;
use crate::{NUM_CHANNELS, SAMPLE_RATE};
use portaudio_rs::device::{get_default_output_index, DeviceIndex, DeviceInfo};
use portaudio_rs::device::{DeviceIndex, DeviceInfo, get_default_output_index};
use portaudio_rs::stream::*;
use std::process::exit;
use std::time::Duration;

View file

@ -10,7 +10,9 @@ use thiserror::Error;
#[derive(Debug, Error)]
enum PulseError {
#[error("<PulseAudioSink> Unsupported Pulseaudio Sample Spec, Format {pulse_format:?} ({format:?}), Channels {channels}, Rate {rate}")]
#[error(
"<PulseAudioSink> Unsupported Pulseaudio Sample Spec, Format {pulse_format:?} ({format:?}), Channels {channels}, Rate {rate}"
)]
InvalidSampleSpec {
pulse_format: pulse::sample::Format,
format: AudioFormat,

View file

@ -5,7 +5,7 @@ use crate::decoder::AudioPacket;
use shell_words::split;
use std::io::{ErrorKind, Write};
use std::process::{exit, Child, Command, Stdio};
use std::process::{Child, Command, Stdio, exit};
use thiserror::Error;
#[derive(Debug, Error)]
@ -68,7 +68,9 @@ pub struct SubprocessSink {
impl Open for SubprocessSink {
fn open(shell_command: Option<String>, format: AudioFormat) -> Self {
if let Some("?") = shell_command.as_deref() {
println!("\nUsage:\n\nOutput to a Subprocess:\n\n\t--backend subprocess --device {{shell_command}}\n");
println!(
"\nUsage:\n\nOutput to a Subprocess:\n\n\t--backend subprocess --device {{shell_command}}\n"
);
exit(0);
}

View file

@ -1,6 +1,6 @@
use std::{mem, str::FromStr, time::Duration};
pub use crate::dither::{mk_ditherer, DithererBuilder, TriangularDitherer};
pub use crate::dither::{DithererBuilder, TriangularDitherer, mk_ditherer};
use crate::{convert::i24, player::duration_to_coefficient};
#[derive(Clone, Copy, Debug, Hash, PartialOrd, Ord, PartialEq, Eq)]

View file

@ -10,8 +10,8 @@ use ogg::{OggReadError, Packet, PacketReader, PacketWriteEndInfo, PacketWriter};
use super::{AudioDecoder, AudioPacket, AudioPacketPosition, DecoderError, DecoderResult};
use crate::{
metadata::audio::{AudioFileFormat, AudioFiles},
MS_PER_PAGE, PAGES_PER_MS,
metadata::audio::{AudioFileFormat, AudioFiles},
};
fn get_header<T>(code: u8, rdr: &mut PacketReader<T>) -> DecoderResult<Vec<u8>>

View file

@ -18,9 +18,9 @@ use symphonia::{
use super::{AudioDecoder, AudioPacket, AudioPacketPosition, DecoderError, DecoderResult};
use crate::{
NUM_CHANNELS, PAGES_PER_MS, SAMPLE_RATE,
metadata::audio::{AudioFileFormat, AudioFiles},
player::NormalisationData,
NUM_CHANNELS, PAGES_PER_MS, SAMPLE_RATE,
};
pub struct SymphoniaDecoder {

View file

@ -1,5 +1,5 @@
use rand::rngs::SmallRng;
use rand::SeedableRng;
use rand::rngs::SmallRng;
use rand_distr::{Distribution, Normal, Triangular, Uniform};
use std::fmt;

View file

@ -3,9 +3,9 @@ use crate::player::{db_to_ratio, ratio_to_db};
use super::mappings::{LogMapping, MappedCtrl, VolumeMapping};
use super::{Mixer, MixerConfig, VolumeCtrl};
use alsa::Error as AlsaError;
use alsa::ctl::{ElemId, ElemIface};
use alsa::mixer::{MilliBel, SelemChannelId, SelemId};
use alsa::Error as AlsaError;
use alsa::{Ctl, Round};
use librespot_core::Error;
@ -106,7 +106,11 @@ impl Mixer for AlsaMixer {
let reported_step_size = (max_millibel - min_millibel).0 / range;
let assumed_step_size = (ZERO_DB - min_millibel).0 / range;
if reported_step_size == assumed_step_size {
warn!("Alsa rounding error detected, setting maximum dB to {:.2} instead of {:.2}", ZERO_DB.to_db(), max_millibel.to_db());
warn!(
"Alsa rounding error detected, setting maximum dB to {:.2} instead of {:.2}",
ZERO_DB.to_db(),
max_millibel.to_db()
);
max_millibel = ZERO_DB;
} else {
warn!("Please manually set `--volume-range` if this is incorrect");

View file

@ -3,8 +3,8 @@ use super::{MappedCtrl, VolumeCtrl};
use super::{Mixer, MixerConfig};
use librespot_core::Error;
use portable_atomic::AtomicU64;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::atomic::Ordering;
#[derive(Clone)]
pub struct SoftMixer {

View file

@ -7,8 +7,8 @@ use std::{
pin::Pin,
process::exit,
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
atomic::{AtomicUsize, Ordering},
},
task::{Context, Poll},
thread,
@ -16,8 +16,8 @@ use std::{
};
use futures_util::{
future, future::FusedFuture, stream::futures_unordered::FuturesUnordered, StreamExt,
TryFutureExt,
StreamExt, TryFutureExt, future, future::FusedFuture,
stream::futures_unordered::FuturesUnordered,
};
use parking_lot::Mutex;
use symphonia::core::io::MediaSource;
@ -28,7 +28,7 @@ use crate::{
audio_backend::Sink,
config::{Bitrate, NormalisationMethod, NormalisationType, PlayerConfig},
convert::Converter,
core::{util::SeqGenerator, Error, Session, SpotifyId},
core::{Error, Session, SpotifyId, util::SeqGenerator},
decoder::{AudioDecoder, AudioPacket, AudioPacketPosition, SymphoniaDecoder},
metadata::audio::{AudioFileFormat, AudioFiles, AudioItem},
mixer::VolumeGetter,
@ -1115,7 +1115,9 @@ impl PlayerTrackLoader {
// If the position is invalid just start from
// the beginning of the track.
let position_ms = if position_ms > duration_ms {
warn!("Invalid start position of {position_ms} ms exceeds track's duration of {duration_ms} ms, starting track from the beginning");
warn!(
"Invalid start position of {position_ms} ms exceeds track's duration of {duration_ms} ms, starting track from the beginning"
);
0
} else {
position_ms
@ -1351,7 +1353,9 @@ impl Future for PlayerInternal {
}
}
Err(e) => {
error!("Skipping to next track, unable to decode samples for track <{track_id:?}>: {e:?}");
error!(
"Skipping to next track, unable to decode samples for track <{track_id:?}>: {e:?}"
);
self.send_event(PlayerEvent::EndOfTrack {
track_id,
play_request_id,
@ -1364,7 +1368,9 @@ impl Future for PlayerInternal {
self.handle_packet(result, normalisation_factor);
}
Err(e) => {
error!("Skipping to next track, unable to get next packet for track <{track_id:?}>: {e:?}");
error!(
"Skipping to next track, unable to get next packet for track <{track_id:?}>: {e:?}"
);
self.send_event(PlayerEvent::EndOfTrack {
track_id,
play_request_id,
@ -1814,7 +1820,10 @@ impl PlayerInternal {
let mut loaded_track = match mem::replace(&mut self.state, PlayerState::Invalid) {
PlayerState::EndOfTrack { loaded_track, .. } => loaded_track,
_ => {
return Err(Error::internal(format!("PlayerInternal::handle_command_load repeating the same track: invalid state: {:?}", self.state)));
return Err(Error::internal(format!(
"PlayerInternal::handle_command_load repeating the same track: invalid state: {:?}",
self.state
)));
}
};
@ -1825,7 +1834,10 @@ impl PlayerInternal {
self.preload = PlayerPreload::None;
self.start_playback(track_id, play_request_id, loaded_track, play);
if let PlayerState::Invalid = self.state {
return Err(Error::internal(format!("PlayerInternal::handle_command_load repeating the same track: start_playback() did not transition to valid player state: {:?}", self.state)));
return Err(Error::internal(format!(
"PlayerInternal::handle_command_load repeating the same track: start_playback() did not transition to valid player state: {:?}",
self.state
)));
}
return Ok(());
}
@ -1894,12 +1906,18 @@ impl PlayerInternal {
self.start_playback(track_id, play_request_id, loaded_track, play);
if let PlayerState::Invalid = self.state {
return Err(Error::internal(format!("PlayerInternal::handle_command_load already playing this track: start_playback() did not transition to valid player state: {:?}", self.state)));
return Err(Error::internal(format!(
"PlayerInternal::handle_command_load already playing this track: start_playback() did not transition to valid player state: {:?}",
self.state
)));
}
return Ok(());
} else {
return Err(Error::internal(format!("PlayerInternal::handle_command_load already playing this track: invalid state: {:?}", self.state)));
return Err(Error::internal(format!(
"PlayerInternal::handle_command_load already playing this track: invalid state: {:?}",
self.state
)));
}
}
}
@ -1924,7 +1942,10 @@ impl PlayerInternal {
self.start_playback(track_id, play_request_id, *loaded_track, play);
return Ok(());
} else {
return Err(Error::internal(format!("PlayerInternal::handle_command_loading preloaded track: invalid state: {:?}", self.state)));
return Err(Error::internal(format!(
"PlayerInternal::handle_command_loading preloaded track: invalid state: {:?}",
self.state
)));
}
}
}
@ -2180,7 +2201,9 @@ impl PlayerInternal {
} = self.state
{
if is_explicit {
warn!("Currently loaded track is explicit, which client setting forbids -- skipping to next track.");
warn!(
"Currently loaded track is explicit, which client setting forbids -- skipping to next track."
);
self.send_event(PlayerEvent::EndOfTrack {
track_id,
play_request_id,

View file

@ -1 +1,2 @@
edition = "2021"
edition = "2024"
style_edition = "2024"