manage 0.12.0

Manage assets and other resources
Documentation
use std::path::{Path, PathBuf};

use refs::{Own, Weak};

use crate::{DataStorage, Managed};

pub trait DataManager<T: Managed> {
    fn root_path() -> &'static Path;
    fn set_root_path(path: impl Into<PathBuf>);

    fn storage() -> &'static mut DataStorage<T>;

    fn full_path(name: &str) -> PathBuf {
        Self::root_path().join(name)
    }

    fn free_with_name(name: impl ToString) {
        Self::storage().remove(&name.to_string());
    }

    fn free(self: Weak<Self>) {
        if self.is_null() {
            return;
        }
        let storage = Self::storage();
        let key = storage
            .iter()
            .find(|(_, val)| val.addr() == self.addr())
            .expect("Failed to find object to free.")
            .0
            .clone();
        storage.remove(&key);
    }

    fn add_with_name(name: &str, create: impl FnOnce() -> T) -> Weak<T> {
        Self::storage()
            .entry(name.to_string())
            .or_insert_with(|| Own::new(create()))
            .weak()
    }

    fn get_static(self: Weak<Self>) -> &'static T {
        Self::storage()
            .iter()
            .find(|(_, val)| val.addr() == self.addr())
            .expect("Failed to get_static managed")
            .1
    }

    fn get_existing(name: impl ToString) -> Option<Weak<T>> {
        Self::storage().get(&name.to_string()).map(Own::weak)
    }

    fn get(name: impl ToString) -> Weak<T> {
        let name = name.to_string();
        let storage = Self::storage();
        let val = storage
            .entry(name.clone())
            .or_insert_with(|| Own::new(T::load_path(&Self::full_path(&name))));
        val.weak()
    }

    fn load(data: &[u8], name: impl ToString) -> Weak<T> {
        let name = name.to_string();
        let storage = Self::storage();
        let val = storage
            .entry(name.clone())
            .or_insert_with(|| Own::new(T::load_data(data, name)));
        val.weak()
    }
}