refs 0.51.0

My vision of reference counting and resources management designed for GUI applications.
Documentation
use std::{
    mem::transmute,
    ops::Deref,
    path::{Path, PathBuf},
};

use anyhow::Result;
use parking_lot::{RwLockReadGuard, RwLockWriteGuard};

use crate::{
    Own, Weak,
    manage::{DataStorage, Managed},
};

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

    fn storage() -> RwLockReadGuard<'static, DataStorage<T>>;
    fn storage_mut() -> RwLockWriteGuard<'static, DataStorage<T>>;

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

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

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

    fn store_with_name<E>(name: &str, create: impl FnOnce() -> Result<T, E>) -> Result<Weak<T>, E> {
        if let Some(entry) = Self::storage().get(name) {
            return Ok(entry.weak());
        }

        let entry = Own::new(create()?);

        let weak = entry.weak();

        Self::storage_mut().insert(name.to_owned(), entry);

        Ok(weak)
    }

    unsafe fn get_static(self: Weak<Self>) -> &'static T {
        let storage = Self::storage();

        let rf = storage
            .iter()
            .find(|(_, val)| val.addr() == self.addr())
            .expect("Failed to get_static managed")
            .1;

        unsafe { transmute(rf.deref()) }
    }

    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();

        if let Some(existing) = Self::storage().get(&name) {
            return existing.weak();
        }

        let new = Own::new(T::load_path(&Self::full_path(&name)));
        let weak = new.weak();

        Self::storage_mut().insert(name, new);

        weak
    }

    fn load(data: &[u8], name: impl ToString) -> Weak<T> {
        let name = name.to_string();

        if let Some(existing) = Self::storage().get(&name) {
            return existing.weak();
        }

        let new = Own::new(T::load_data(data, &name));
        let weak = new.weak();

        Self::storage_mut().insert(name, new);

        weak
    }

    #[allow(async_fn_in_trait)]
    async fn download(name: impl ToString, url: &str) -> Result<Weak<T>> {
        let name = name.to_string();

        let data = reqwest::get(url).await?.bytes().await?;

        Ok(Self::load(&data, &name))
    }
}