Add lib.rs and constructors

main
mat ess 2023-04-18 22:05:13 -04:00
parent bd64f45e56
commit 6e32657ac0
3 changed files with 41 additions and 8 deletions

1
src/lib.rs Normal file
View File

@ -0,0 +1 @@
pub mod library;

View File

@ -1,15 +1,22 @@
use nanoserde::DeJson;
use std::{ use std::{
collections::HashSet, collections::HashSet,
hash::{Hash, Hasher}, hash::{Hash, Hasher},
}; };
use nanoserde::DeJson;
#[derive(Debug, Clone, DeJson)] #[derive(Debug, Clone, DeJson)]
pub struct Library { pub struct Library {
artists: HashSet<Artist>, artists: HashSet<Artist>,
} }
impl Library { impl Library {
pub fn new(artists: impl IntoIterator<Item = Artist>) -> Library {
Library {
artists: artists.into_iter().collect(),
}
}
fn all_covers(&self) -> HashSet<&Song> { fn all_covers(&self) -> HashSet<&Song> {
self.artists self.artists
.iter() .iter()
@ -28,7 +35,7 @@ impl Library {
} }
#[derive(Debug, Clone, PartialEq, Eq, DeJson)] #[derive(Debug, Clone, PartialEq, Eq, DeJson)]
struct Artist { pub struct Artist {
name: String, name: String,
members: HashSet<String>, members: HashSet<String>,
catalog: HashSet<Song>, catalog: HashSet<Song>,
@ -41,6 +48,18 @@ impl Hash for Artist {
} }
impl Artist { impl Artist {
pub fn new(
name: String,
members: impl IntoIterator<Item = String>,
catalog: impl IntoIterator<Item = Song>,
) -> Artist {
Artist {
name,
members: members.into_iter().collect(),
catalog: catalog.into_iter().collect(),
}
}
fn covered_songs(&self) -> HashSet<&Song> { fn covered_songs(&self) -> HashSet<&Song> {
self.catalog self.catalog
.iter() .iter()
@ -64,6 +83,18 @@ impl Hash for Song {
} }
impl Song { impl Song {
pub fn new(
title: String,
performer: String,
writers: impl IntoIterator<Item = String>,
) -> Song {
Song {
title,
performer,
writers: writers.into_iter().collect(),
}
}
fn is_library_cover(&self, library: &Library) -> bool { fn is_library_cover(&self, library: &Library) -> bool {
library library
.artists .artists
@ -187,13 +218,13 @@ mod tests {
fn library() -> Library { fn library() -> Library {
Library { Library {
artists: HashSet::from([bm(), ts(), bon_iver()]), artists: [bm(), ts(), bon_iver()].into(),
} }
} }
#[test] #[test]
fn test_covered_songs() { fn test_covered_songs() {
assert!(bm().covered_songs() == HashSet::from([&love_story("black midi"), &schizoid_man()])) assert!(bm().covered_songs() == [&love_story("black midi"), &schizoid_man()].into())
} }
#[test] #[test]
@ -203,7 +234,7 @@ mod tests {
#[test] #[test]
fn test_find_covers() { fn test_find_covers() {
assert!(library().find_library_covers() == HashSet::from([&love_story("black midi")])) assert!(library().find_library_covers() == [&love_story("black midi")].into())
} }
#[test] #[test]

View File

@ -1,14 +1,15 @@
use nanoserde::DeJson;
use std::{env, fs}; use std::{env, fs};
mod library; use nanoserde::DeJson;
use cover::library::Library;
fn main() { fn main() {
let file_path = env::args() let file_path = env::args()
.nth(1) .nth(1)
.expect("Usage: cover path/to/library.json"); .expect("Usage: cover path/to/library.json");
let json = fs::read_to_string(file_path).expect("Failed to open library file"); let json = fs::read_to_string(file_path).expect("Failed to open library file");
let library: library::Library = let library: Library =
DeJson::deserialize_json(&json).expect("Failed to deserialize library file"); DeJson::deserialize_json(&json).expect("Failed to deserialize library file");
for cover in library.find_library_covers() { for cover in library.find_library_covers() {
println!("Found cover!"); println!("Found cover!");