use super::*;
pub fn plan_playlist_artifacts(
desired: &[PlaylistDesired],
stored: &BTreeMap<String, PlaylistState>,
can_delete: bool,
list_fully_enumerated: bool,
local: &HashMap<String, LocalFile>,
) -> Vec<Action> {
let mut actions: Vec<Action> = Vec::new();
let desired_ids: BTreeSet<&str> = desired.iter().map(|d| d.id.as_str()).collect();
for d in desired {
let stored_here = stored.get(&d.id);
let needs_write = needs_write_drift(
stored_here.map(|state| (state.hash.as_str(), state.path.as_str())),
d.hash.as_str(),
d.path.as_str(),
local,
);
if needs_write {
actions.push(Action::WriteArtifact {
kind: ArtifactKind::Playlist,
path: d.path.clone(),
source_url: String::new(),
hash: d.hash.clone(),
owner_id: d.id.clone(),
content: Some(d.content.clone()),
});
}
if let Some(state) = stored_here
&& state.path != d.path
&& let Some(action) = delete_playlist_artifact_action(
&d.id,
&state.path,
can_delete,
list_fully_enumerated,
)
{
actions.push(action);
}
}
for (id, state) in stored {
if !desired_ids.contains(id.as_str())
&& let Some(action) =
delete_playlist_artifact_action(id, &state.path, can_delete, list_fully_enumerated)
{
actions.push(action);
}
}
actions.sort_by(|a, b| playlist_action_key(a).cmp(&playlist_action_key(b)));
suppress_path_aliasing(&mut actions);
actions
}
fn playlist_action_key(action: &Action) -> (&str, u8) {
match action {
Action::WriteArtifact { owner_id, .. } => (owner_id.as_str(), 0),
Action::DeleteArtifact { owner_id, .. } => (owner_id.as_str(), 1),
Action::Skip { clip_id } => (clip_id.as_str(), 2),
_ => ("", 3),
}
}
pub(crate) fn delete_playlist_artifact_action(
owner_id: &str,
path: &str,
can_delete: bool,
list_fully_enumerated: bool,
) -> Option<Action> {
if !can_delete || !list_fully_enumerated || path.is_empty() {
return None;
}
Some(Action::DeleteArtifact {
kind: ArtifactKind::Playlist,
path: path.to_string(),
owner_id: owner_id.to_string(),
})
}