moved files to root
This commit is contained in:
135
src/manifest/mod.rs
Normal file
135
src/manifest/mod.rs
Normal file
@@ -0,0 +1,135 @@
|
||||
// pub mod v1;
|
||||
|
||||
pub mod song;
|
||||
use song::Song;
|
||||
|
||||
use std::{collections::HashMap, fmt::{Debug, Display}, path::PathBuf};
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
const DEFAULT_MANIFEST: &'static str = include_str!("../../manifest.default.json");
|
||||
|
||||
pub type GenreName = String;
|
||||
pub type SongName = String;
|
||||
pub type Genre = HashMap<SongName, song::Song>;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||
pub enum Format {
|
||||
#[default]
|
||||
m4a,
|
||||
aac,
|
||||
flac,
|
||||
mp3,
|
||||
vaw,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
|
||||
pub struct Manifest {
|
||||
#[serde(skip)]
|
||||
path: PathBuf,
|
||||
format: Format,
|
||||
genres: HashMap<GenreName, Genre>
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Manifest {
|
||||
pub fn get_format(&self) -> &Format {
|
||||
&self.format
|
||||
}
|
||||
pub fn add_song(&mut self, genre: GenreName, name: SongName, song: Song) -> Option<Song> {
|
||||
self.get_genre_mut(genre)?.insert(name, song)
|
||||
}
|
||||
pub fn get_song(&self, genre: GenreName, name: &SongName) -> Option<&Song> {
|
||||
self.get_genre(genre)?.get(name)
|
||||
}
|
||||
pub fn get_song_mut(&mut self, genre: GenreName, name: &SongName) -> Option<&mut Song> {
|
||||
self.get_genre_mut(genre)?.get_mut(name)
|
||||
}
|
||||
pub fn add_genre(&mut self, name: GenreName) {
|
||||
self.genres.insert(name, Default::default());
|
||||
}
|
||||
pub fn get_genre(&self, name: GenreName) -> Option<&Genre> {
|
||||
self.genres.get(&name)
|
||||
}
|
||||
pub fn get_genre_mut(&mut self, name: GenreName) -> Option<&mut Genre> {
|
||||
self.genres.get_mut(&name)
|
||||
}
|
||||
pub fn get_genres(&self) -> &HashMap<GenreName, Genre> {
|
||||
&self.genres
|
||||
}
|
||||
pub fn get_genres_mut(&mut self) -> &mut HashMap<GenreName, Genre> {
|
||||
&mut self.genres
|
||||
}
|
||||
pub fn get_song_count(&self) -> usize {
|
||||
let mut count = 0;
|
||||
for (_, v) in &self.genres {
|
||||
count += v.len();
|
||||
}
|
||||
count
|
||||
}
|
||||
pub fn load(&mut self, p: Option<&PathBuf>) -> Result<()> {
|
||||
let path = p.unwrap_or(&self.path);
|
||||
log::debug!("Path: {path:?}");
|
||||
let data = std::fs::read_to_string(path)?;
|
||||
|
||||
let s: Self = serde_json::from_str(data.as_str())?;
|
||||
self.genres = s.genres;
|
||||
self.format = s.format;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn save(&self, p: Option<&PathBuf>) -> Result<()> {
|
||||
let path = p.unwrap_or(&self.path);
|
||||
log::debug!("Path: {path:?}");
|
||||
let data = serde_json::to_string_pretty(self)?;
|
||||
std::fs::write(path, data)?;
|
||||
Ok(())
|
||||
}
|
||||
pub fn load_new(p: &PathBuf) -> Result<Self> {
|
||||
|
||||
if !p.exists() {
|
||||
std::fs::write(p, DEFAULT_MANIFEST)?;
|
||||
}
|
||||
|
||||
let mut s = Self::default();
|
||||
log::debug!("Path: {p:?}");
|
||||
s.path = p.clone();
|
||||
s.load(Some(p))?;
|
||||
Ok(s)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
impl TryFrom<String> for Format {
|
||||
type Error = anyhow::Error;
|
||||
fn try_from(value: String) -> std::prelude::v1::Result<Self, Self::Error> {
|
||||
match value.as_str() {
|
||||
"m4a" => Ok(Self::m4a),
|
||||
"aac" => Ok(Self::aac),
|
||||
"flac" => Ok(Self::flac),
|
||||
"mp3" => Ok(Self::mp3),
|
||||
"vaw" => Ok(Self::vaw),
|
||||
v => bail!("Unknown format {v}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl Display for Format {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Format::m4a => write!(f, "m4a")?,
|
||||
Format::aac => write!(f, "aac")?,
|
||||
Format::flac => write!(f, "flac")?,
|
||||
Format::mp3 => write!(f, "mp3")?,
|
||||
Format::vaw => write!(f, "vaw")?,
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
77
src/manifest/song.rs
Normal file
77
src/manifest/song.rs
Normal file
@@ -0,0 +1,77 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub enum SongType {
|
||||
Youtube,
|
||||
Spotify,
|
||||
Soundcloud,
|
||||
}
|
||||
|
||||
impl ToString for SongType {
|
||||
fn to_string(&self) -> String {
|
||||
let s = match self {
|
||||
SongType::Youtube => "Youtube",
|
||||
SongType::Spotify => "Spotify",
|
||||
SongType::Soundcloud => "Soundcloud",
|
||||
};
|
||||
String::from(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct Song {
|
||||
url: String,
|
||||
typ: SongType
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Song {
|
||||
pub fn from_url_str(url: String) -> Result<Self> {
|
||||
Self::from_url(url::Url::from_str(url.as_str())?)
|
||||
}
|
||||
|
||||
pub fn from_url(url: url::Url) -> Result<Self> {
|
||||
Ok(Self {
|
||||
url: url.to_string(),
|
||||
typ: url.try_into()?,
|
||||
})
|
||||
}
|
||||
pub fn get_url(&self) -> Result<url::Url> {
|
||||
Ok(url::Url::from_str(&self.url)?)
|
||||
}
|
||||
pub fn get_url_str(&self) -> &String {
|
||||
&self.url
|
||||
}
|
||||
pub fn get_url_str_mut(&mut self) -> &mut String {
|
||||
&mut self.url
|
||||
}
|
||||
pub fn get_type(&self) -> &SongType {
|
||||
&self.typ
|
||||
}
|
||||
pub fn get_type_mut(&mut self) -> &mut SongType {
|
||||
&mut self.typ
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
impl TryFrom<url::Url> for SongType {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(url: url::Url) -> std::prelude::v1::Result<Self, Self::Error> {
|
||||
let Some(host) = url.host_str() else {
|
||||
bail!("{url} does not have a host");
|
||||
};
|
||||
|
||||
match host {
|
||||
"youtube.com" | "youtu.be" | "www.youtube.com" => Ok(Self::Youtube),
|
||||
"open.spotify.com" => Ok(Self::Spotify),
|
||||
"SOUNDCLOUD" => Ok(Self::Soundcloud), // TODO: Fix this
|
||||
_ => bail!("Unknwon host {url}")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user