2026-10-03 16:40:17 +02:00
|
|
|
use crate::{Apply, CommandError, Edit, Editor, File, State, Track, update_selected};
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
pub struct Metadata<'a> {
|
|
|
|
|
pub name: &'a str,
|
|
|
|
|
pub desc: &'a str,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Apply for Metadata<'_> {
|
|
|
|
|
fn apply(mut self, state: &mut State) -> Result<(), CommandError> {
|
|
|
|
|
update_selected(state, &mut self);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Editor for Metadata<'_> {
|
|
|
|
|
fn file(&mut self, file: &mut File) -> Edit {
|
|
|
|
|
file.info.name = self.name.to_owned();
|
|
|
|
|
file.info.desc = Some(self.desc.to_owned());
|
2026-10-04 11:00:46 +02:00
|
|
|
// a single track is named like the file
|
|
|
|
|
if let [track] = file.trk.as_mut_slice() {
|
|
|
|
|
track.info.name = Some(self.name.to_owned());
|
|
|
|
|
}
|
2026-10-03 16:40:17 +02:00
|
|
|
Edit::Changed
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn track(&mut self, track: &mut Track) -> Edit {
|
|
|
|
|
track.info.name = Some(self.name.to_owned());
|
|
|
|
|
track.info.desc = Some(self.desc.to_owned());
|
|
|
|
|
Edit::Changed
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|
use std::collections::HashSet;
|
|
|
|
|
|
2026-10-04 11:00:46 +02:00
|
|
|
use crate::{New, NewTrack, Selection, engine::command::fixture::Fixture};
|
2026-10-03 16:40:17 +02:00
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_metadata_applies_to_selected_file() {
|
|
|
|
|
let mut fx = Fixture::default();
|
2026-10-07 17:58:17 +02:00
|
|
|
New {
|
|
|
|
|
name: "first",
|
|
|
|
|
trackpoint: None,
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
|
|
|
|
New {
|
|
|
|
|
name: "second",
|
|
|
|
|
trackpoint: None,
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap(); // now selected
|
2026-10-03 16:40:17 +02:00
|
|
|
let selected = *fx.selected_files().iter().next().unwrap();
|
|
|
|
|
|
|
|
|
|
Metadata {
|
|
|
|
|
name: "renamed",
|
|
|
|
|
desc: "description",
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
for (id, file) in fx.files.iter() {
|
|
|
|
|
if *id == selected {
|
|
|
|
|
assert_eq!(file.info.name, "renamed");
|
|
|
|
|
assert_eq!(file.info.desc.as_deref(), Some("description"));
|
|
|
|
|
} else {
|
|
|
|
|
assert_eq!(file.info.name, "first");
|
|
|
|
|
assert_eq!(file.info.desc, None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_metadata_applies_to_selected_track() {
|
|
|
|
|
let mut fx = Fixture::default();
|
|
|
|
|
let data = std::fs::read("data/with_tracks.gpx").unwrap();
|
2026-10-04 11:07:12 +02:00
|
|
|
crate::Load {
|
|
|
|
|
data: &data,
|
|
|
|
|
name: "file",
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
2026-10-03 16:40:17 +02:00
|
|
|
let file = fx.files.values().next().unwrap().clone();
|
|
|
|
|
fx.selection = Selection::Track {
|
|
|
|
|
file_id: file.id,
|
|
|
|
|
trk_ids: HashSet::from([file.trk[0].id]),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Metadata {
|
|
|
|
|
name: "renamed",
|
|
|
|
|
desc: "",
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
|
|
|
|
|
|
|
|
|
let after = &fx.files[&file.id];
|
|
|
|
|
assert_eq!(after.info.name, file.info.name);
|
|
|
|
|
assert_eq!(after.trk[0].info.name.as_deref(), Some("renamed"));
|
|
|
|
|
assert_eq!(after.trk[1].info, file.trk[1].info);
|
|
|
|
|
}
|
2026-10-04 11:00:46 +02:00
|
|
|
|
|
|
|
|
/// A new file with `nb_tracks` tracks (without name), selected.
|
|
|
|
|
fn file_with_tracks(fx: &mut Fixture, nb_tracks: usize) {
|
2026-10-07 17:58:17 +02:00
|
|
|
New {
|
|
|
|
|
name: "file",
|
|
|
|
|
trackpoint: None,
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
2026-10-04 11:00:46 +02:00
|
|
|
for _ in 0..nb_tracks {
|
|
|
|
|
NewTrack.apply(&mut fx.state()).unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn rename(fx: &mut Fixture) {
|
|
|
|
|
Metadata {
|
|
|
|
|
name: "renamed",
|
|
|
|
|
desc: "",
|
|
|
|
|
}
|
|
|
|
|
.apply(&mut fx.state())
|
|
|
|
|
.unwrap();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_single_track_is_renamed_like_the_file() {
|
|
|
|
|
let mut fx = Fixture::default();
|
|
|
|
|
file_with_tracks(&mut fx, 1);
|
|
|
|
|
rename(&mut fx);
|
|
|
|
|
let file = fx.files.values().next().unwrap();
|
|
|
|
|
assert_eq!(file.info.name, "renamed");
|
|
|
|
|
assert_eq!(file.trk[0].info.name.as_deref(), Some("renamed"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_single_track_with_a_name_is_renamed_too() {
|
|
|
|
|
let mut fx = Fixture::default();
|
|
|
|
|
file_with_tracks(&mut fx, 1);
|
|
|
|
|
let id = *fx.files.keys().next().unwrap();
|
|
|
|
|
std::rc::Rc::make_mut(fx.files.get_mut(&id).unwrap()).trk[0]
|
|
|
|
|
.info
|
|
|
|
|
.name = Some("track".to_owned());
|
|
|
|
|
rename(&mut fx);
|
|
|
|
|
let file = &fx.files[&id];
|
|
|
|
|
assert_eq!(file.info.name, "renamed");
|
|
|
|
|
assert_eq!(file.trk[0].info.name.as_deref(), Some("renamed"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_several_tracks_are_not_renamed() {
|
|
|
|
|
let mut fx = Fixture::default();
|
|
|
|
|
file_with_tracks(&mut fx, 2);
|
|
|
|
|
rename(&mut fx);
|
|
|
|
|
let file = fx.files.values().next().unwrap();
|
|
|
|
|
assert_eq!(file.info.name, "renamed");
|
|
|
|
|
assert!(file.trk.iter().all(|trk| trk.info.name.is_none()));
|
|
|
|
|
}
|
2026-10-03 16:40:17 +02:00
|
|
|
}
|