pub struct LineageStore {
pub schema_version: u32,
pub albums: BTreeMap<String, AlbumArt>,
pub playlists: BTreeMap<String, PlaylistState>,
/* private fields */
}Expand description
Fields§
§schema_version: u32On-disk schema version, so a future migration can branch on it.
albums: BTreeMap<String, AlbumArt>The reconciled folder-art state per album, keyed by the album’s stable
root id (HARDENING H2). Additive: absent in older stores. pub so the
CLI executor and reconcile can borrow it across the crate boundary.
playlists: BTreeMap<String, PlaylistState>The reconciled .m3u8 state per playlist, keyed by the playlist’s Suno
id (the synthetic "liked" id for the liked feed). Additive: absent in
older stores. pub for the same cross-crate borrow as albums.
Implementations§
Source§impl LineageStore
impl LineageStore
Sourcepub fn set_album_overrides(&mut self, overrides: BTreeMap<String, String>)
pub fn set_album_overrides(&mut self, overrides: BTreeMap<String, String>)
Layer this run’s manual album-name overrides onto the store.
Keyed by lineage root id, from config each run and never persisted
(#[serde(skip)]). Applied wherever the album title is resolved
(context_for, album_for_id, colliding_root_titles), so one
call makes the path, ALBUM tag, change hash, index, and disambiguation
all reflect the preferred name from one source.
Sourcepub fn refresh_eligible_roots(&mut self)
pub fn refresh_eligible_roots(&mut self)
Recompute the eligible-root set from the resolution cache.
The non-empty root_ids across the cache’s values — exactly what
colliding_root_titles groups over. Called at the end of update and
after a load (the field is not serialised).
Sourcepub fn get_root(&self, id: &str) -> Option<&CacheEntry>
pub fn get_root(&self, id: &str) -> Option<&CacheEntry>
The cached root resolution for id, if present.
Sourcepub fn context_for(&self, clip: &Clip) -> LineageContext
pub fn context_for(&self, clip: &Clip) -> LineageContext
Build a LineageContext for clip from the durable store.
The source of truth for every file-affecting lineage decision (album folder, embedded tags, change hash), so a dropped resolution call never rewrites the library (HARDENING H3). The root comes from the monotonic cache (the clip’s own id when the store has no better answer), its title and date from that root’s archived node, so a transient miss keeps the last-known-good album (even a since-purged ancestor) and the Year tag anchors on the root’s year. The parent edge is read structurally.
Sourcepub fn album_for_id(&self, id: &str) -> String
pub fn album_for_id(&self, id: &str) -> String
The canonical logical album title for a clip identified only by id.
The store-side counterpart of context_for(clip).album(clip.title) when
no live Clip is on hand. Title and root come from the archived nodes
and the monotonic cache, then the LineageContext::album rule decides
whether the clip folders under its root’s album or its own title. A clip
absent from the store folds to a self-root with an empty title.
Sourcepub fn colliding_root_titles(&self) -> BTreeSet<String>
pub fn colliding_root_titles(&self) -> BTreeSet<String>
The set of effective album titles shared by more than one distinct root.
Two distinct roots must never share an album folder, so naming appends the
short root id to the album of any clip whose album is in this set.
Computed from the whole archive — every eligible root paired with its
effective title (override when configured, else the node title) — so the
decision is stable across runs and independent of the current batch: a
--since/--limit slice showing only one of two same-titled roots still
disambiguates rather than oscillating.
It iterates the same eligible-root set that
effective_root_title gates overrides on,
so the two can never disagree. A root with no node and no override has an
empty effective title and is skipped.
Sourcepub fn update(&mut self, clips: &[Clip], resolution: &Resolution, now: &str)
pub fn update(&mut self, clips: &[Clip], resolution: &Resolution, now: &str)
Fold this run’s clips and their Resolution into the store.
Pure: it takes now (an ISO timestamp) from the caller rather than
reading a clock. Upserts a node for every clip and every gap-filled
ancestor (so trashed ancestors are archived), upserts an edge for every
lineage_edges link, and refreshes the monotonic resolution cache.
edges is left sorted so the serialised form is deterministic.
Sourcepub fn archived_parents(&self) -> HashMap<String, String>
pub fn archived_parents(&self) -> HashMap<String, String>
The persisted child_id -> parent_id map from the active primary edges
(each clip’s ordinal-0 lineage parent), for seeding
resolve_roots.
This lets a resolution walk hop through an ancestor whose clip is absent this run (an intermediate remix, or one Suno has purged) using the link captured on an earlier run, instead of self-rooting. It is resolution input only: these ids are never download candidates.
Source§impl LineageStore
impl LineageStore
Sourcepub fn refresh_display_name(&mut self, display_name: &str) -> bool
pub fn refresh_display_name(&mut self, display_name: &str) -> bool
Refresh the pinned owner’s display name when it has changed, returning whether it changed. A no-op when the library is not pinned.
Trait Implementations§
Source§impl Clone for LineageStore
impl Clone for LineageStore
Source§fn clone(&self) -> LineageStore
fn clone(&self) -> LineageStore
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for LineageStore
impl Debug for LineageStore
Source§impl Default for LineageStore
impl Default for LineageStore
Source§impl<'de> Deserialize<'de> for LineageStorewhere
LineageStore: Default,
impl<'de> Deserialize<'de> for LineageStorewhere
LineageStore: Default,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for LineageStore
Equality over the durable graph only.
impl PartialEq for LineageStore
Equality over the durable graph only.
album_overrides and eligible_root_ids are runtime-only overlays
(#[serde(skip)]): the first is layered from config each run, the second is
a cache derived from resolution_cache. Neither is part of the persisted
relational shape, so two stores are equal when their durable content is,
regardless of the overrides in force or whether the derived set has been
refreshed after a load.