Improved SpotifyId implementation

Moved conversion of SpotifyAudioType from and to &str directly to traits
Used a simpler and more idiomatic syntax in some places.
This commit is contained in:
johannesd3 2021-01-29 11:50:50 +01:00
parent 6b09836117
commit e582f0a3fc

View file

@ -1,4 +1,4 @@
use std; use std::convert::TryInto;
use std::fmt; use std::fmt;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -8,42 +8,24 @@ pub enum SpotifyAudioType {
NonPlayable, NonPlayable,
} }
impl SpotifyAudioType { impl From<&str> for SpotifyAudioType {
fn from_str(src: &str) -> SpotifyAudioType { fn from(v: &str) -> Self {
match src { match v {
"track" => SpotifyAudioType::Track, "track" => SpotifyAudioType::Track,
"episode" => SpotifyAudioType::Podcast, "episode" => SpotifyAudioType::Podcast,
_ => SpotifyAudioType::NonPlayable, _ => SpotifyAudioType::NonPlayable,
} }
} }
}
fn to_str(self) -> &'static str { impl Into<&str> for SpotifyAudioType {
fn into(self) -> &'static str {
match self { match self {
SpotifyAudioType::Track => "track", SpotifyAudioType::Track => "track",
SpotifyAudioType::Podcast => "episode", SpotifyAudioType::Podcast => "episode",
SpotifyAudioType::NonPlayable => "unknown", SpotifyAudioType::NonPlayable => "unknown",
} }
} }
fn len(self) -> usize {
match self {
SpotifyAudioType::Track => 5,
SpotifyAudioType::Podcast => 7,
SpotifyAudioType::NonPlayable => 7,
}
}
}
impl std::convert::From<&str> for SpotifyAudioType {
fn from(v: &str) -> Self {
SpotifyAudioType::from_str(v)
}
}
impl std::convert::Into<&str> for SpotifyAudioType {
fn into(self) -> &'static str {
self.to_str()
}
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -119,14 +101,10 @@ impl SpotifyId {
/// ///
/// The resulting `SpotifyId` will default to a `SpotifyAudioType::TRACK`. /// The resulting `SpotifyId` will default to a `SpotifyAudioType::TRACK`.
pub fn from_raw(src: &[u8]) -> Result<SpotifyId, SpotifyIdError> { pub fn from_raw(src: &[u8]) -> Result<SpotifyId, SpotifyIdError> {
if src.len() != SpotifyId::SIZE { match src.try_into() {
return Err(SpotifyIdError); Ok(dst) => Ok(SpotifyId::as_track(u128::from_be_bytes(dst))),
}; Err(_) => Err(SpotifyIdError),
}
let mut dst = [0u8; SpotifyId::SIZE];
dst.copy_from_slice(src);
Ok(SpotifyId::as_track(u128::from_be_bytes(dst)))
} }
/// Parses a [Spotify URI] into a `SpotifyId`. /// Parses a [Spotify URI] into a `SpotifyId`.
@ -143,10 +121,7 @@ impl SpotifyId {
return Err(SpotifyIdError); return Err(SpotifyIdError);
} }
let mut id = match SpotifyId::from_base62(&src[id_i..]) { let mut id = SpotifyId::from_base62(&src[id_i..])?;
Ok(v) => v,
Err(e) => return Err(e),
};
// Slice offset by 8 as we are skipping the "spotify:" prefix. // Slice offset by 8 as we are skipping the "spotify:" prefix.
id.audio_type = src[8..id_i - 1].into(); id.audio_type = src[8..id_i - 1].into();
@ -225,10 +200,11 @@ impl SpotifyId {
pub fn to_uri(&self) -> String { pub fn to_uri(&self) -> String {
// 8 chars for the "spotify:" prefix + 1 colon + 22 chars base62 encoded ID = 31 // 8 chars for the "spotify:" prefix + 1 colon + 22 chars base62 encoded ID = 31
// + unknown size audio_type. // + unknown size audio_type.
let mut dst = String::with_capacity(31 + self.audio_type.len()); let audio_type: &str = self.audio_type.into();
let mut dst = String::with_capacity(31 + audio_type.len());
dst.push_str("spotify:"); dst.push_str("spotify:");
dst.push_str(self.audio_type.into()); dst.push_str(audio_type);
dst.push_str(":"); dst.push(':');
dst.push_str(&self.to_base62()); dst.push_str(&self.to_base62());
dst dst