xmpd/xmpd-manifest/src/song.rs

121 lines
3.0 KiB
Rust

use std::{fmt::Display, str::FromStr};
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd, Default)]
pub enum IconType {
CustomUrl(url::Url),
FromSource,
#[default]
None
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd)]
pub struct Song {
name: String,
author: String,
url: url::Url,
source_type: SourceType,
#[serde(default)]
icon_type: IconType,
#[serde(default)]
genres: Vec<String>,
/// Seconds
#[serde(default)]
length: usize,
}
impl Song {
pub fn new(url: &url::Url, source_type: SourceType) -> crate::Result<Self> {
Ok(Self {
name: String::default(),
author: String::default(),
source_type,
icon_type: IconType::None,
url: url.clone(),
genres: Vec::new(),
length: 0
})
}
pub fn new_from_str(url: &str, source_type: SourceType) -> crate::Result<Self> {
Self::new(&url::Url::from_str(url)?, source_type)
}
pub fn name(&self) -> &str {
&self.name
}
pub fn author(&self) -> &str {
&self.author
}
pub fn url(&self) -> &url::Url {
&self.url
}
pub fn source_type(&self) -> &SourceType {
&self.source_type
}
pub fn icon_type(&self) -> &IconType {
&self.icon_type
}
pub fn genres(&self) -> &[String] {
&self.genres
}
pub fn length(&self) -> usize {
self.length
}
pub fn set_name(&mut self, v: &str) {
self.name = v.to_string();
}
pub fn set_author(&mut self, v: &str) {
self.author = v.to_string();
}
pub fn set_url(&mut self, v: &url::Url) {
self.url.clone_from(v);
}
pub fn set_source_type(&mut self, v: &SourceType) {
self.source_type.clone_from(v);
}
pub fn set_icon_type(&mut self, v: &IconType) {
self.icon_type.clone_from(v);
}
pub fn genres_mut(&mut self) -> &mut Vec<String> {
&mut self.genres
}
pub fn set_length(&mut self, l: usize) {
self.length = l;
}
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, PartialOrd)]
pub enum SourceType {
Youtube,
Spotify,
Soundcloud,
HttpBare,
HttpZip,
Http7z
}
impl SourceType {
fn from_url(url: &url::Url) -> Option<Self> {
match url.host_str() {
Some("youtube.com") | Some("youtu.be") =>
Some(Self::Youtube),
Some("open.spotify.com") =>
Some(Self::Spotify),
Some("soundcloud.com") | Some("on.soundcloud.com") =>
Some(Self::Soundcloud),
_ => None
}
}
}
impl Display for SourceType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Youtube => write!(f, "YouTube"),
Self::Soundcloud => write!(f, "SoundCloud"),
Self::Spotify => write!(f, "Spotify"),
s => write!(f, "{s:?}"),
}
}
}