Extract display
Some checks failed
Cargo CI / Build and Test (pull_request) Successful in 1m56s
Cargo CI / Lint (pull_request) Failing after 1m7s

This commit is contained in:
Wojciech Kozlowski 2024-08-29 15:58:58 +02:00
parent 0f049e40ee
commit dbabc1c55f
2 changed files with 226 additions and 219 deletions

219
src/tui/ui/display.rs Normal file
View File

@ -0,0 +1,219 @@
use musichoard::collection::{album::{Album, AlbumDate, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, AlbumStatus}, track::{TrackFormat, TrackQuality}};
pub struct UiDisplay;
impl UiDisplay {
pub fn display_date(date: &AlbumDate, seq: &AlbumSeq) -> String {
if seq.0 > 0 {
format!("{} ({})", Self::display_album_date(date), seq.0)
} else {
Self::display_album_date(date)
}
}
pub fn display_album_date(date: &AlbumDate) -> String {
match date.year {
Some(year) => match date.month {
Some(month) => match date.day {
Some(day) => format!("{year}{month:02}{day:02}"),
None => format!("{year}{month:02}"),
},
None => format!("{year}"),
},
None => String::from(""),
}
}
pub fn display_type(
primary: &Option<AlbumPrimaryType>,
secondary: &Vec<AlbumSecondaryType>,
) -> String {
match primary {
Some(ref primary) => {
if secondary.is_empty() {
Self::display_primary_type(primary).to_string()
} else {
format!(
"{} ({})",
Self::display_primary_type(primary),
Self::display_secondary_types(secondary)
)
}
}
None => String::default(),
}
}
pub fn display_primary_type(value: &AlbumPrimaryType) -> &'static str {
match value {
AlbumPrimaryType::Album => "Album",
AlbumPrimaryType::Single => "Single",
AlbumPrimaryType::Ep => "EP",
AlbumPrimaryType::Broadcast => "Broadcast",
AlbumPrimaryType::Other => "Other",
}
}
pub fn display_secondary_types(values: &Vec<AlbumSecondaryType>) -> String {
let mut types: Vec<&'static str> = vec![];
for value in values {
match value {
AlbumSecondaryType::Compilation => types.push("Compilation"),
AlbumSecondaryType::Soundtrack => types.push("Soundtrack"),
AlbumSecondaryType::Spokenword => types.push("Spokenword"),
AlbumSecondaryType::Interview => types.push("Interview"),
AlbumSecondaryType::Audiobook => types.push("Audiobook"),
AlbumSecondaryType::AudioDrama => types.push("Audio drama"),
AlbumSecondaryType::Live => types.push("Live"),
AlbumSecondaryType::Remix => types.push("Remix"),
AlbumSecondaryType::DjMix => types.push("DJ-mix"),
AlbumSecondaryType::MixtapeStreet => types.push("Mixtape/Street"),
AlbumSecondaryType::Demo => types.push("Demo"),
AlbumSecondaryType::FieldRecording => types.push("Field recording"),
}
}
types.join(", ")
}
pub fn display_album_status(status: &AlbumStatus) -> &'static str {
match status {
AlbumStatus::None => "None",
AlbumStatus::Owned(format) => match format {
TrackFormat::Mp3 => "MP3",
TrackFormat::Flac => "FLAC",
},
}
}
pub fn display_matching_info(matching: Option<&Album>) -> String {
match matching {
Some(matching) => format!(
"Matching: {} | {}",
UiDisplay::display_album_date(&matching.date),
&matching.id.title
),
None => String::from("Matching: nothing"),
}
}
pub fn display_track_quality(quality: &TrackQuality) -> String {
match quality.format {
TrackFormat::Flac => "FLAC".to_string(),
TrackFormat::Mp3 => format!("MP3 {}kbps", quality.bitrate),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn display_album_date() {
assert_eq!(UiDisplay::display_album_date(&AlbumDate::default()), "");
assert_eq!(UiDisplay::display_album_date(&1990.into()), "1990");
assert_eq!(UiDisplay::display_album_date(&(1990, 5).into()), "199005");
assert_eq!(
UiDisplay::display_album_date(&(1990, 5, 6).into()),
"19900506"
);
}
#[test]
fn display_date() {
let date: AlbumDate = 1990.into();
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq::default()), "1990");
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq(0)), "1990");
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq(5)), "1990 (5)");
}
#[test]
fn display_primary_type() {
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Album),
"Album"
);
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Single),
"Single"
);
assert_eq!(UiDisplay::display_primary_type(&AlbumPrimaryType::Ep), "EP");
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Broadcast),
"Broadcast"
);
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Other),
"Other"
);
}
#[test]
fn display_secondary_types() {
assert_eq!(
UiDisplay::display_secondary_types(&vec![
AlbumSecondaryType::Compilation,
AlbumSecondaryType::Soundtrack,
AlbumSecondaryType::Spokenword,
AlbumSecondaryType::Interview,
AlbumSecondaryType::Audiobook,
AlbumSecondaryType::AudioDrama,
AlbumSecondaryType::Live,
AlbumSecondaryType::Remix,
AlbumSecondaryType::DjMix,
AlbumSecondaryType::MixtapeStreet,
AlbumSecondaryType::Demo,
AlbumSecondaryType::FieldRecording,
]),
"Compilation, Soundtrack, Spokenword, Interview, Audiobook, Audio drama, Live, Remix, \
DJ-mix, Mixtape/Street, Demo, Field recording"
);
}
#[test]
fn display_type() {
assert_eq!(UiDisplay::display_type(&None, &vec![]), "");
assert_eq!(
UiDisplay::display_type(&Some(AlbumPrimaryType::Album), &vec![]),
"Album"
);
assert_eq!(
UiDisplay::display_type(
&Some(AlbumPrimaryType::Album),
&vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation]
),
"Album (Live, Compilation)"
);
}
#[test]
fn display_album_status() {
assert_eq!(UiDisplay::display_album_status(&AlbumStatus::None), "None");
assert_eq!(
UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Mp3)),
"MP3"
);
assert_eq!(
UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Flac)),
"FLAC"
);
}
#[test]
fn display_track_quality() {
assert_eq!(
UiDisplay::display_track_quality(&TrackQuality {
format: TrackFormat::Flac,
bitrate: 1411
}),
"FLAC"
);
assert_eq!(
UiDisplay::display_track_quality(&TrackQuality {
format: TrackFormat::Mp3,
bitrate: 218
}),
"MP3 218kbps"
);
}
}

View File

@ -1,16 +1,14 @@
mod browse;
mod display;
mod minibuffer;
use std::collections::HashMap;
use browse::{AlbumArea, AlbumState, ArtistArea, ArtistState, FrameArea, TrackArea, TrackState};
use display::UiDisplay;
use minibuffer::Minibuffer;
use musichoard::collection::{
album::{Album, AlbumDate, AlbumPrimaryType, AlbumSecondaryType, AlbumSeq, AlbumStatus},
artist::Artist,
musicbrainz::IMusicBrainzRef,
track::{Track, TrackFormat, TrackQuality},
Collection,
album::Album, artist::Artist, musicbrainz::IMusicBrainzRef, track::Track, Collection,
};
use ratatui::{
layout::{Alignment, Rect},
@ -538,113 +536,12 @@ impl IUi for Ui {
}
}
pub struct UiDisplay;
impl UiDisplay {
fn display_date(date: &AlbumDate, seq: &AlbumSeq) -> String {
if seq.0 > 0 {
format!("{} ({})", Self::display_album_date(date), seq.0)
} else {
Self::display_album_date(date)
}
}
fn display_album_date(date: &AlbumDate) -> String {
match date.year {
Some(year) => match date.month {
Some(month) => match date.day {
Some(day) => format!("{year}{month:02}{day:02}"),
None => format!("{year}{month:02}"),
},
None => format!("{year}"),
},
None => String::from(""),
}
}
fn display_type(
primary: &Option<AlbumPrimaryType>,
secondary: &Vec<AlbumSecondaryType>,
) -> String {
match primary {
Some(ref primary) => {
if secondary.is_empty() {
Self::display_primary_type(primary).to_string()
} else {
format!(
"{} ({})",
Self::display_primary_type(primary),
Self::display_secondary_types(secondary)
)
}
}
None => String::default(),
}
}
fn display_primary_type(value: &AlbumPrimaryType) -> &'static str {
match value {
AlbumPrimaryType::Album => "Album",
AlbumPrimaryType::Single => "Single",
AlbumPrimaryType::Ep => "EP",
AlbumPrimaryType::Broadcast => "Broadcast",
AlbumPrimaryType::Other => "Other",
}
}
fn display_secondary_types(values: &Vec<AlbumSecondaryType>) -> String {
let mut types: Vec<&'static str> = vec![];
for value in values {
match value {
AlbumSecondaryType::Compilation => types.push("Compilation"),
AlbumSecondaryType::Soundtrack => types.push("Soundtrack"),
AlbumSecondaryType::Spokenword => types.push("Spokenword"),
AlbumSecondaryType::Interview => types.push("Interview"),
AlbumSecondaryType::Audiobook => types.push("Audiobook"),
AlbumSecondaryType::AudioDrama => types.push("Audio drama"),
AlbumSecondaryType::Live => types.push("Live"),
AlbumSecondaryType::Remix => types.push("Remix"),
AlbumSecondaryType::DjMix => types.push("DJ-mix"),
AlbumSecondaryType::MixtapeStreet => types.push("Mixtape/Street"),
AlbumSecondaryType::Demo => types.push("Demo"),
AlbumSecondaryType::FieldRecording => types.push("Field recording"),
}
}
types.join(", ")
}
fn display_album_status(status: &AlbumStatus) -> &'static str {
match status {
AlbumStatus::None => "None",
AlbumStatus::Owned(format) => match format {
TrackFormat::Mp3 => "MP3",
TrackFormat::Flac => "FLAC",
},
}
}
fn display_matching_info(matching: Option<&Album>) -> String {
match matching {
Some(matching) => format!(
"Matching: {} | {}",
UiDisplay::display_album_date(&matching.date),
&matching.id.title
),
None => String::from("Matching: nothing"),
}
}
fn display_track_quality(quality: &TrackQuality) -> String {
match quality.format {
TrackFormat::Flac => "FLAC".to_string(),
TrackFormat::Mp3 => format!("MP3 {}kbps", quality.bitrate),
}
}
}
#[cfg(test)]
mod tests {
use musichoard::collection::{album::AlbumId, artist::ArtistId};
use musichoard::collection::{
album::{AlbumDate, AlbumId, AlbumPrimaryType, AlbumSecondaryType},
artist::ArtistId,
};
use crate::tui::{
app::{AppPublic, AppPublicInner, AppPublicMatches, Delta},
@ -779,113 +676,4 @@ mod tests {
draw_test_suite(artists, &mut selection);
}
#[test]
fn display_album_date() {
assert_eq!(UiDisplay::display_album_date(&AlbumDate::default()), "");
assert_eq!(UiDisplay::display_album_date(&1990.into()), "1990");
assert_eq!(UiDisplay::display_album_date(&(1990, 5).into()), "199005");
assert_eq!(
UiDisplay::display_album_date(&(1990, 5, 6).into()),
"19900506"
);
}
#[test]
fn display_date() {
let date: AlbumDate = 1990.into();
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq::default()), "1990");
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq(0)), "1990");
assert_eq!(UiDisplay::display_date(&date, &AlbumSeq(5)), "1990 (5)");
}
#[test]
fn display_primary_type() {
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Album),
"Album"
);
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Single),
"Single"
);
assert_eq!(UiDisplay::display_primary_type(&AlbumPrimaryType::Ep), "EP");
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Broadcast),
"Broadcast"
);
assert_eq!(
UiDisplay::display_primary_type(&AlbumPrimaryType::Other),
"Other"
);
}
#[test]
fn display_secondary_types() {
assert_eq!(
UiDisplay::display_secondary_types(&vec![
AlbumSecondaryType::Compilation,
AlbumSecondaryType::Soundtrack,
AlbumSecondaryType::Spokenword,
AlbumSecondaryType::Interview,
AlbumSecondaryType::Audiobook,
AlbumSecondaryType::AudioDrama,
AlbumSecondaryType::Live,
AlbumSecondaryType::Remix,
AlbumSecondaryType::DjMix,
AlbumSecondaryType::MixtapeStreet,
AlbumSecondaryType::Demo,
AlbumSecondaryType::FieldRecording,
]),
"Compilation, Soundtrack, Spokenword, Interview, Audiobook, Audio drama, Live, Remix, \
DJ-mix, Mixtape/Street, Demo, Field recording"
);
}
#[test]
fn display_type() {
assert_eq!(UiDisplay::display_type(&None, &vec![]), "");
assert_eq!(
UiDisplay::display_type(&Some(AlbumPrimaryType::Album), &vec![]),
"Album"
);
assert_eq!(
UiDisplay::display_type(
&Some(AlbumPrimaryType::Album),
&vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation]
),
"Album (Live, Compilation)"
);
}
#[test]
fn display_album_status() {
assert_eq!(UiDisplay::display_album_status(&AlbumStatus::None), "None");
assert_eq!(
UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Mp3)),
"MP3"
);
assert_eq!(
UiDisplay::display_album_status(&AlbumStatus::Owned(TrackFormat::Flac)),
"FLAC"
);
}
#[test]
fn display_track_quality() {
assert_eq!(
UiDisplay::display_track_quality(&TrackQuality {
format: TrackFormat::Flac,
bitrate: 1411
}),
"FLAC"
);
assert_eq!(
UiDisplay::display_track_quality(&TrackQuality {
format: TrackFormat::Mp3,
bitrate: 218
}),
"MP3 218kbps"
);
}
}