Load older sessions whose track height is the bare Fit string (#447)

This commit is contained in:
MarekSpodBiedry
2026-10-13 17:52:29 +02:00
parent c0cb993408
commit 9a398d79ff
2 changed files with 68 additions and 0 deletions
+13
View File
@@ -681,6 +681,19 @@ mod tests {
assert_eq!(back, s);
}
#[test]
fn session_with_legacy_fit_height_loads() {
let mut s = Session::default();
let t = s.add_track(TrackKind::Audio, ChannelFormat::Stereo, None);
if let Some(track) = s.track_mut(t) {
track.height = crate::TrackHeight::Large;
}
let text = s.to_json().unwrap().replace("\"height\": \"Large\"", "\"height\": \"Fit\"");
assert!(text.contains("\"height\": \"Fit\""));
let back = Session::from_json(&text).unwrap();
assert_eq!(back.track(t).map(|tr| tr.height), Some(crate::TrackHeight::Medium));
}
#[test]
fn video_clip_round_trips_and_old_sessions_load() {
let mut s = Session::default();
+55
View File
@@ -84,6 +84,7 @@ impl TrackKind {
/// Track heights (View › Track Height presets).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, serde::Serialize, serde::Deserialize)]
#[serde(from = "TrackHeightRepr")]
pub enum TrackHeight {
/// Any height from Micro to Extreme, in points.
Custom(u16),
@@ -99,6 +100,51 @@ pub enum TrackHeight {
Fit(u16),
}
/// What a saved track height may look like: the current form, or the bare `"Fit"` string older sessions used.
#[derive(serde::Deserialize)]
#[serde(untagged)]
enum TrackHeightRepr {
Current(TrackHeightCurrent),
LegacyFit(LegacyFit),
}
#[derive(serde::Deserialize)]
enum LegacyFit {
Fit,
}
/// Mirror of `TrackHeight` that derives the current serialized form.
#[derive(serde::Deserialize)]
enum TrackHeightCurrent {
Custom(u16),
Micro,
Mini,
Small,
Medium,
Large,
Jumbo,
Extreme,
Fit(u16),
}
impl From<TrackHeightRepr> for TrackHeight {
fn from(repr: TrackHeightRepr) -> Self {
match repr {
TrackHeightRepr::Current(TrackHeightCurrent::Custom(p)) => TrackHeight::Custom(p),
TrackHeightRepr::Current(TrackHeightCurrent::Micro) => TrackHeight::Micro,
TrackHeightRepr::Current(TrackHeightCurrent::Mini) => TrackHeight::Mini,
TrackHeightRepr::Current(TrackHeightCurrent::Small) => TrackHeight::Small,
TrackHeightRepr::Current(TrackHeightCurrent::Medium) => TrackHeight::Medium,
TrackHeightRepr::Current(TrackHeightCurrent::Large) => TrackHeight::Large,
TrackHeightRepr::Current(TrackHeightCurrent::Jumbo) => TrackHeight::Jumbo,
TrackHeightRepr::Current(TrackHeightCurrent::Extreme) => TrackHeight::Extreme,
TrackHeightRepr::Current(TrackHeightCurrent::Fit(p)) => TrackHeight::Fit(p),
// Older sessions stored Fit with no size, drawn 88 points tall: the default Medium height.
TrackHeightRepr::LegacyFit(LegacyFit::Fit) => TrackHeight::Medium,
}
}
}
impl TrackHeight {
pub const ALL: [TrackHeight; 7] = [
TrackHeight::Micro,
@@ -328,6 +374,15 @@ impl Track {
mod tests {
use super::*;
#[test]
fn legacy_fit_string_loads_as_default_height() {
assert_eq!(serde_json::from_str::<TrackHeight>("\"Fit\"").unwrap(), TrackHeight::Medium);
assert_eq!(serde_json::from_str::<TrackHeight>("{\"Fit\":120}").unwrap(), TrackHeight::Fit(120));
assert_eq!(serde_json::to_string(&TrackHeight::Fit(120)).unwrap(), "{\"Fit\":120}");
assert_eq!(serde_json::from_str::<TrackHeight>("\"Large\"").unwrap(), TrackHeight::Large);
assert_eq!(serde_json::from_str::<TrackHeight>("{\"Custom\":50}").unwrap(), TrackHeight::Custom(50));
}
#[test]
fn new_track_defaults() {
let t = Track::new(TrackId(1), "Gtr", TrackKind::Audio, ChannelFormat::Stereo, TRACK_COLORS[0]);