muzzman-lib 0.3.5

Modulabile Download manager
Documentation
use std::{
    fmt::Debug,
    hash::Hash,
    sync::{Arc, RwLock},
    thread::JoinHandle,
};

use serde::{Deserialize, Serialize};

use crate::prelude::*;
use bytes_kman::TBytes;

#[derive(Debug, Clone, Serialize, Deserialize, bytes_kman::Bytes)]
pub enum ElementNotify {
    Complited,
    ModuleChanged(Option<ModuleId>),
    StatusChanged(usize),
    Progress(f32),
}

impl_get_ref!(ElementNotify);

#[derive(
    Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, bytes_kman::Bytes,
)]
pub struct ElementId {
    pub uid: u64,
    pub location_id: LocationId,
}

impl ElementId {
    pub fn into_ref(self, session: Box<dyn TSession>) -> RefElement {
        RefElement {
            session: Some(session),
            id: self,
        }
    }
}

#[derive(Serialize, Deserialize)]
pub struct RefElement {
    #[serde(skip)]
    pub session: Option<Box<dyn TSession>>,
    pub id: ElementId,
}

unsafe impl Sync for RefElement {}
unsafe impl Send for RefElement {}

impl Debug for RefElement {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("RefElement").field("id", &self.id).finish()
    }
}

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

pub trait TElement {
    fn get_session(&self) -> Result<Box<dyn TSession>, SessionError>;

    fn get_meta(&self) -> Result<String, SessionError>;
    fn set_meta(&self, meta: &str) -> Result<(), SessionError>;

    fn get_element_data(&self) -> Result<Data, SessionError>;
    fn set_element_data(&self, data: Data) -> Result<(), SessionError>;

    fn get_module_data(&self) -> Result<Data, SessionError>;
    fn set_module_data(&self, data: Data) -> Result<(), SessionError>;

    fn get_module(&self) -> Result<Option<MRef>, SessionError>;
    fn set_module(&self, module: Option<ModuleId>) -> Result<(), SessionError>;

    fn resolv_module(&self) -> Result<bool, SessionError>;
    fn init(&self) -> Result<bool, SessionError>;

    fn get_url(&self) -> Result<Option<String>, SessionError>;
    fn set_url(&self, url: Option<String>) -> Result<(), SessionError>;

    fn get_statuses(&self) -> Result<Vec<String>, SessionError>;
    fn set_statuses(&self, statuses: Vec<String>) -> Result<(), SessionError>;

    fn get_status(&self) -> Result<usize, SessionError>;
    fn get_status_msg(&self) -> Result<String, SessionError>;
    fn set_status(&self, status: usize) -> Result<(), SessionError>;

    fn get_data(&self) -> Result<FileOrData, SessionError>;
    fn set_data(&self, data: FileOrData) -> Result<(), SessionError>;

    fn get_progress(&self) -> Result<f32, SessionError>;
    fn set_progress(&self, progress: f32) -> Result<(), SessionError>;

    fn get_should_save(&self) -> Result<bool, SessionError>;
    fn set_should_save(&self, should_save: bool) -> Result<(), SessionError>;

    fn is_enabled(&self) -> Result<bool, SessionError>;
    fn set_enabled(&self, enabled: bool, storage: Option<Storage>) -> Result<(), SessionError>;

    fn get_element_info(&self) -> Result<ElementInfo, SessionError>;

    fn wait(&self) -> Result<(), SessionError>;

    fn destroy(self) -> Result<ERow, SessionError>;

    fn id(&self) -> ElementId;
}

pub struct Element {
    pub name: String,
    pub desc: String,
    pub meta: String,
    pub url: Option<String>,
    pub element_data: Data,
    pub module_data: Data,
    pub module: Option<MRef>,
    pub statuses: Vec<String>,
    pub status: usize,
    pub data: FileOrData,
    pub progress: f32,
    pub should_save: bool,
    pub enabled: bool,
    pub thread: Option<JoinHandle<()>>,
    pub events: Arc<RwLock<Events>>,
    pub info: ERef,
}

unsafe impl Sync for Element {}
unsafe impl Send for Element {}

pub trait TRowElement {
    fn set_status(&self, status: usize);
}

impl TRowElement for ERow {
    fn set_status(&self, status: usize) {
        {
            let mut element = self.write().unwrap();
            element.status = status;
        }
    }
}

impl Debug for Element {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("RowElement")
            .field("name", &self.name)
            .field("desc", &self.desc)
            .field("meta", &self.meta)
            .field("element_data", &self.element_data)
            .field("module_data", &self.module_data)
            .field("statuses", &self.statuses)
            .field("data", &self.data)
            .field("progress", &self.progress)
            .field("should_save", &self.should_save)
            .field("enable", &self.enabled)
            .field("thread", &self.thread)
            .finish()
    }
}

impl TElement for ERef {
    fn get_session(&self) -> Result<Box<dyn TSession>, SessionError> {
        if let Some(session) = &self.read().unwrap().session {
            return Ok(session.c());
        }
        Err(SessionError::InvalidSession)
    }

    fn get_meta(&self) -> Result<String, SessionError> {
        self.get_session()?.element_get_meta(&self.id())
    }

    fn set_meta(&self, meta: &str) -> Result<(), SessionError> {
        self.get_session()?.element_set_meta(&self.id(), meta)
    }

    fn get_element_data(&self) -> Result<Data, SessionError> {
        self.get_session()?.element_get_element_data(&self.id())
    }

    fn set_element_data(&self, data: Data) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_element_data(&self.id(), data)
    }

    fn get_module_data(&self) -> Result<Data, SessionError> {
        self.get_session()?.element_get_module_data(&self.id())
    }

    fn set_module_data(&self, data: Data) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_module_data(&self.id(), data)
    }

    fn get_module(&self) -> Result<Option<MRef>, SessionError> {
        self.get_session()?.element_get_module(&self.id())
    }

    fn set_module(&self, module: Option<ModuleId>) -> Result<(), SessionError> {
        self.get_session()?.element_set_module(&self.id(), module)
    }

    fn resolv_module(&self) -> Result<bool, SessionError> {
        self.get_session()?.element_resolv_module(&self.id())
    }

    fn init(&self) -> Result<bool, SessionError> {
        if let Some(module) = &self.get_module()? {
            self.get_session()?
                .module_init_element(&module.id(), &self.id())?;
            Ok(true)
        } else {
            Ok(false)
        }
    }

    fn get_statuses(&self) -> Result<Vec<String>, SessionError> {
        self.get_session()?.element_get_statuses(&self.id())
    }

    fn set_statuses(&self, statuses: Vec<String>) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_statuses(&self.id(), statuses)
    }

    fn get_status(&self) -> Result<usize, SessionError> {
        self.get_session()?.element_get_status(&self.id())
    }

    fn get_status_msg(&self) -> Result<String, SessionError> {
        if let Some(status) = self.get_statuses()?.get(self.get_status()?) {
            Ok(status.clone())
        } else {
            Ok(String::from("None"))
        }
    }

    fn set_status(&self, status: usize) -> Result<(), SessionError> {
        self.get_session()?.element_set_status(&self.id(), status)
    }

    fn get_data(&self) -> Result<FileOrData, SessionError> {
        self.get_session()?.element_get_data(&self.id())
    }

    fn set_data(&self, data: FileOrData) -> Result<(), SessionError> {
        self.get_session()?.element_set_data(&self.id(), data)
    }

    fn get_progress(&self) -> Result<f32, SessionError> {
        self.get_session()?.element_get_progress(&self.id())
    }

    fn set_progress(&self, progress: f32) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_progress(&self.id(), progress)
    }

    fn get_should_save(&self) -> Result<bool, SessionError> {
        self.get_session()?.element_get_should_save(&self.id())
    }

    fn set_should_save(&self, should_save: bool) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_should_save(&self.id(), should_save)
    }

    fn is_enabled(&self) -> Result<bool, SessionError> {
        self.get_session()?.element_get_enabled(&self.id())
    }

    fn set_enabled(&self, enabled: bool, storage: Option<Storage>) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_enabled(&self.id(), enabled, storage)
    }

    fn get_element_info(&self) -> Result<ElementInfo, SessionError> {
        self.get_session()?.element_get_element_info(&self.id())
    }

    fn wait(&self) -> Result<(), SessionError> {
        self.get_session()?.element_wait(&self.id())
    }

    fn destroy(self) -> Result<ERow, SessionError> {
        self.get_session()?.destroy_element(self.id())
    }

    fn id(&self) -> ElementId {
        self.read().unwrap().id.clone()
    }

    fn get_url(&self) -> Result<Option<String>, SessionError> {
        self.get_session()?.element_get_url(&self.id())
    }

    fn set_url(&self, url: Option<String>) -> Result<(), SessionError> {
        self.get_session()?.element_set_url(&self.id(), url)
    }
}

impl Common for ERef {
    fn get_name(&self) -> Result<String, SessionError> {
        self.get_session()?.element_get_name(&self.id())
    }

    fn set_name(&self, name: impl Into<String>) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_name(&self.id(), &name.into())
    }

    fn get_desc(&self) -> Result<String, SessionError> {
        self.get_session()?.element_get_desc(&self.id())
    }

    fn set_desc(&self, desc: impl Into<String>) -> Result<(), SessionError> {
        self.get_session()?
            .element_set_desc(&self.id(), &desc.into())
    }

    fn notify(&self, event: Event) -> Result<(), SessionError> {
        self.get_session()?.element_notify(&self.id(), event)
    }

    fn emit(&self, event: Event) -> Result<(), SessionError> {
        self.get_session()?.element_emit(&self.id(), event)
    }

    fn subscribe(&self, _ref: ID) -> Result<(), SessionError> {
        self.get_session()?.element_subscribe(&self.id(), _ref)
    }

    fn unsubscribe(&self, _ref: ID) -> Result<(), SessionError> {
        self.get_session()?.element_unsubscribe(&self.id(), _ref)
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, bytes_kman::Bytes)]
pub struct ElementInfo {
    pub name: String,
    pub desc: String,
    pub meta: String,
    pub element_data: Data,
    pub module_data: Data,
    pub module: Option<ModuleInfo>,
    pub statuses: Vec<String>,
    pub status: usize,
    pub data: FileOrData,
    pub progress: f32,
    pub should_save: bool,
    pub enabled: bool,
    pub id: ElementId,
}

impl Hash for ElementInfo {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.name.hash(state);
        self.desc.hash(state);
        self.meta.hash(state);
        self.element_data.hash(state);
        self.module_data.hash(state);
        self.statuses.hash(state);
        self.status.hash(state);
        self.data.hash(state);
        self.enabled.hash(state);
        (self.progress as i32).hash(state)
    }
}

impl TGetLogger for ERef {
    fn get_logger(&self, dst: Option<Arc<std::sync::Mutex<std::fs::File>>>) -> Logger {
        Logger::for_element(dst, self.clone())
    }
}

impl TGetLogger for ERow {
    fn get_logger(&self, dst: Option<Arc<std::sync::Mutex<std::fs::File>>>) -> Logger {
        let info = self.read().unwrap().info.clone();
        Logger::for_element(dst, info)
    }
}