use serde::{Deserialize, Serialize};
use super::{JsonStore, StoreLocation};
#[cfg(test)]
use crate::app::ViewKind;
use crate::{app::ViewData, types::PlayQueue};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionState {
pub data: ViewData,
pub queue: PlayQueue,
pub show_queue: bool,
pub volume: f32,
pub repeat: bool,
pub library_expanded: bool,
#[serde(default)]
pub search_scope: crate::providers::SearchScope,
#[serde(default)]
pub search_provider: crate::providers::ProviderId,
pub lyrics_provider: crate::lyrics::LyricsProvider,
}
impl Default for SessionState {
fn default() -> Self {
Self {
data: ViewData::default(),
queue: PlayQueue::new(),
show_queue: false,
volume: 0.8,
repeat: false,
library_expanded: true,
search_scope: crate::providers::SearchScope::Songs,
search_provider: crate::providers::ProviderId::YouTube,
lyrics_provider: crate::lyrics::LyricsProvider::default(),
}
}
}
impl JsonStore for SessionState {
const FILE: &'static str = "session.json";
const LOCATION: StoreLocation = StoreLocation::Cache;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn session_state_default() {
let state = SessionState::default();
assert!(matches!(state.data.kind, ViewKind::Search { .. }));
assert!(state.queue.tracks.is_empty());
assert!(!state.show_queue);
assert!((state.volume - 0.8).abs() < f32::EPSILON);
assert_eq!(state.lyrics_provider, crate::lyrics::LyricsProvider::LrcLib);
}
#[test]
fn session_state_round_trip() {
let state = SessionState {
data: ViewData {
kind: ViewKind::ArtistRadio("Test Radio".into()),
content: crate::load_state::LoadState::Ready(Vec::new()),
selection: vec![2],
scroll: 42.0,
request_id: 0,
},
queue: PlayQueue::default(),
show_queue: true,
volume: 0.5,
repeat: true,
library_expanded: false,
search_scope: crate::providers::SearchScope::Songs,
search_provider: crate::providers::ProviderId::YouTube,
lyrics_provider: crate::lyrics::LyricsProvider::LrcLib,
};
let json = serde_json::to_string(&state).unwrap();
let restored: SessionState = serde_json::from_str(&json).unwrap();
assert!(matches!(
restored.data.kind,
ViewKind::SongRadio(_) | ViewKind::ArtistRadio(_)
));
assert!(restored.show_queue);
assert!((restored.volume - 0.5).abs() < f32::EPSILON);
assert!(restored.repeat);
assert!(!restored.library_expanded);
assert_eq!(
restored.lyrics_provider,
crate::lyrics::LyricsProvider::LrcLib
);
if let ViewKind::ArtistRadio(label) = &restored.data.kind {
assert_eq!(label, "Test Radio");
assert_eq!(restored.data.selection, vec![2]);
assert!((restored.data.scroll - 42.0).abs() < f32::EPSILON);
} else {
panic!("expected Radio data");
}
}
}