/* This file is part of jellything (https://codeberg.org/metamuffin/jellything) which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin */ use jellycommon::{ jellyobject::{Object, ObjectBuffer, Tag, TypedTag, ValueStore}, *, }; use std::marker::PhantomData; pub struct SourceRanks { list: Vec, } #[derive(Clone, Copy)] pub struct ImportSource<'a> { pub tag: Tag, pub ranks: &'a SourceRanks, } pub trait ObjectImportSourceExt { fn insert_s(&self, is: ImportSource, key: TypedTag, value: T) -> ObjectBuffer; } impl<'a> ObjectImportSourceExt for Object<'a> { fn insert_s( &self, is: ImportSource, key: TypedTag, value: T, ) -> ObjectBuffer { let ms = self.get(NO_METASOURCE).unwrap_or_default(); let ms_key = TypedTag::(key.0, PhantomData); if let Some(current_source) = ms.get(ms_key) { if !is.ranks.compare(key.0, current_source, is.tag) { return self.dump(); } } self.insert(key, value) .as_object() .update(NO_METASOURCE, |ms| ms.insert(ms_key, is.tag)) } } impl SourceRanks { pub fn new() -> Self { Self { list: [ MSOURCE_EXPLICIT, MSOURCE_TRAKT, MSOURCE_MUSICBRAINZ, MSOURCE_MEDIA, MSOURCE_TAGS, MSOURCE_IMAGE_ATT, MSOURCE_TMDB, MSOURCE_WIKIDATA, MSOURCE_VGMDB, MSOURCE_ACOUSTID, MSOURCE_INFOJSON, MSOURCE_OMDB, ] .to_vec(), } } pub fn compare(&self, key: Tag, old: Tag, new: Tag) -> bool { let _ = key; let old_index = self .list .iter() .position(|e| *e == old) .unwrap_or(usize::MAX); let new_index = self .list .iter() .position(|e| *e == new) .unwrap_or(usize::MAX); new_index <= old_index } }