selene-core 0.2.0

selene-core is the backend for Selene, a local-first music player
Documentation
use std::path::PathBuf;

use sled::Tree;

use crate::{
    config::common::LoudnormConfig,
    database::{DatabaseEntry, Patchable, patch_option_replace, patch_replace, track_tree},
    ffmpeg::loudnorm::LoudnormAnalysis,
    library::{
        cover_art::CoverArt,
        track::{Track, TrackId, track_meta::TrackMeta},
    },
    media_container::MediaContainer,
};

impl DatabaseEntry for Track {
    type Id = TrackId;
    const VERSION_NUMBER: u32 = 1;

    fn tree() -> Tree {
        track_tree()
    }

    fn id(&self) -> TrackId {
        self.id
    }
}

impl PartialEq for Track {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

impl Eq for Track {}

impl std::hash::Hash for Track {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        state.write(self.id.as_bytes());
    }
}

pub struct PatchTrack {
    pub(crate) src_container: Option<MediaContainer>,
    pub(crate) lib_container: Option<MediaContainer>,
    pub(crate) relative_library_path: Option<PathBuf>,
    metadata: TrackMeta,
    cover_art: Option<CoverArt>,
    pub(crate) loudnorm_analysis: Option<LoudnormAnalysis>,
    pub(crate) applied_loudnorm: Option<LoudnormConfig>,
}

impl Patchable<PatchTrack> for Track {
    fn patch(&mut self, patch: PatchTrack) {
        patch_replace(&mut self.src_container, patch.src_container);
        patch_option_replace(&mut self.lib_container, patch.lib_container);
        patch_replace(&mut self.relative_library_path, patch.relative_library_path);
        self.metadata.patch(patch.metadata);
        patch_option_replace(&mut self.cover_art, patch.cover_art);
        patch_option_replace(&mut self.loudnorm_analysis, patch.loudnorm_analysis);
        patch_option_replace(&mut self.applied_loudnorm, patch.applied_loudnorm);
    }
}

impl From<Track> for PatchTrack {
    fn from(value: Track) -> Self {
        PatchTrack {
            src_container: Some(value.src_container),
            lib_container: value.lib_container,
            relative_library_path: Some(value.relative_library_path),
            metadata: value.metadata,
            cover_art: value.cover_art,
            loudnorm_analysis: value.loudnorm_analysis,
            applied_loudnorm: value.applied_loudnorm,
        }
    }
}

impl Patchable<Self> for Track {
    fn patch(&mut self, patch: Self) {
        self.patch(PatchTrack::from(patch));
    }
}