muzzman-lib 0.3.5

Modulabile Download manager
Documentation
use bytes_kman::TBytes;
use std::fmt::Debug;
use std::hash::Hash;
use std::net::{IpAddr, TcpStream};
use std::ops::Range;
use std::path::PathBuf;
use std::str::FromStr;
use std::sync::{Arc, Mutex, RwLock};
use std::thread::JoinHandle;

use serde::{Deserialize, Serialize};

use crate::prelude::*;

#[derive(Clone, Debug, Serialize, Deserialize, bytes_kman::Bytes)]
pub enum LocationNotify {
    ElementNotify(usize, ElementNotify),
    ModuleChanged(Option<ModuleId>),
    ElementsAllCompleted,
    Completed,
}

impl_get_ref!(LocationNotify);

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ServerLocation {
    pub ip: IpAddr,
    pub port: u16,
    pub indentification: String,
    pub server_cert: Option<String>,
    #[serde(skip)]
    pub conn: Option<Arc<Mutex<TcpStream>>>,
}

impl TBytes for ServerLocation {
    fn size(&self) -> usize {
        self.ip.to_string().size()
            + self.port.size()
            + self.indentification.size()
            + self.server_cert.size()
    }

    fn to_bytes(&self) -> Vec<u8> {
        let mut buff = Vec::with_capacity(self.size());

        buff.append(&mut self.ip.to_string().to_bytes());
        buff.append(&mut self.port.to_bytes());
        buff.append(&mut self.indentification.to_bytes());
        buff.append(&mut self.server_cert.to_bytes());

        buff
    }

    fn from_bytes(buffer: &mut Vec<u8>) -> Option<Self>
    where
        Self: Sized,
    {
        let ip = String::from_bytes(buffer)?;
        let port = u16::from_bytes(buffer)?;
        let indentification = String::from_bytes(buffer)?;
        let server_cert = <Option<String>>::from_bytes(buffer)?;

        let ip = IpAddr::from_str(&ip).unwrap();

        Some(Self {
            ip,
            port,
            indentification,
            server_cert,
            conn: None,
        })
    }
}

impl Hash for ServerLocation {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.ip.hash(state);
        self.port.hash(state);
        self.indentification.hash(state);
        self.server_cert.hash(state);
    }
}

#[derive(Debug, Clone, Serialize, Deserialize, Hash, bytes_kman::Bytes)]
pub struct LocalLocation {
    pub path: PathBuf,
}

#[derive(Debug, Clone, Serialize, Deserialize, Hash, bytes_kman::Bytes)]
pub enum WhereIsLocation {
    Server(ServerLocation),
    Local(LocalLocation),
}

#[derive(
    Default,
    Debug,
    Clone,
    Serialize,
    Deserialize,
    PartialEq,
    Eq,
    PartialOrd,
    Ord,
    Hash,
    bytes_kman::Bytes,
)]
pub struct LocationId(pub Vec<u64>);

impl std::ops::Deref for LocationId {
    type Target = Vec<u64>;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl std::ops::DerefMut for LocationId {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl std::iter::IntoIterator for LocationId {
    type Item = u64;

    type IntoIter = std::vec::IntoIter<u64>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.into_iter()
    }
}

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

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

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

impl Clone for RefLocation {
    fn clone(&self) -> Self {
        Self {
            id: self.id.clone(),
            session: if let Some(session) = &self.session {
                Some(session.c())
            } else {
                None
            },
        }
    }
}

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

pub struct Location {
    pub name: String,
    pub desc: String,
    pub where_is: WhereIsLocation,
    pub shoud_save: bool,
    pub elements: Vec<ERow>,
    pub locations: Vec<LRow>,
    pub info: LRef,
    pub path: PathBuf,
    pub thread: Option<JoinHandle<()>>,
    pub module: Option<MRef>,
    pub events: Arc<RwLock<Events>>,
}

impl TLocation for LRef {
    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_path(&self) -> Result<PathBuf, SessionError> {
        self.get_session()?.location_get_path(&self.id())
    }

    fn set_path(&self, path: PathBuf) -> Result<(), SessionError> {
        self.get_session()?.location_set_path(&self.id(), path)
    }

    fn get_where_is(&self) -> Result<WhereIsLocation, SessionError> {
        self.get_session()?.location_get_where_is(&self.id())
    }

    fn set_where_is(&self, where_is: WhereIsLocation) -> Result<(), SessionError> {
        self.get_session()?
            .location_set_where_is(&self.id(), where_is)
    }

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

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

    fn get_elements(&self, range: Range<usize>) -> Result<Vec<ERef>, SessionError> {
        self.get_session()?.location_get_elements(&self.id(), range)
    }

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

    fn get_locations(&self, range: Range<usize>) -> Result<Vec<LRef>, SessionError> {
        self.get_session()?.get_locations(&self.id(), range)
    }

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

    fn get_location_info(&self) -> Result<LocationInfo, SessionError> {
        self.get_session()?.location_get_location_info(&self.id())
    }

    fn create_element(&self, name: &str) -> Result<ERef, SessionError> {
        self.get_session()?.create_element(name, &self.id())
    }

    fn create_location(&self, name: &str) -> Result<LRef, SessionError> {
        self.get_session()?.create_location(name, &self.id())
    }

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

    fn _move(&self, to: &LocationId) -> Result<(), SessionError> {
        self.get_session()?.move_location(&self.id(), to)
    }

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

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

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

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

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

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

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

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

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

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

    fn get_path(&self) -> Result<PathBuf, SessionError>;
    fn set_path(&self, path: PathBuf) -> Result<(), SessionError>;

    fn get_where_is(&self) -> Result<WhereIsLocation, SessionError>;
    fn set_where_is(&self, where_is: WhereIsLocation) -> Result<(), SessionError>;

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

    fn get_elements(&self, range: Range<usize>) -> Result<Vec<ERef>, SessionError>;
    fn get_elements_len(&self) -> Result<usize, SessionError>;
    fn get_locations(&self, range: Range<usize>) -> Result<Vec<LRef>, SessionError>;
    fn get_locations_len(&self) -> Result<usize, SessionError>;

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

    fn create_element(&self, name: &str) -> Result<ERef, SessionError>;
    fn create_location(&self, name: &str) -> Result<LRef, SessionError>;

    fn destroy(self) -> Result<LRow, SessionError>;
    fn _move(&self, to: &LocationId) -> Result<(), SessionError>;

    fn id(&self) -> LocationId;
}

#[derive(Clone, Debug, Serialize, Deserialize, Hash, bytes_kman::Bytes)]
pub struct LocationInfo {
    pub name: String,
    pub desc: String,
    // hash
    pub id: LocationId,
    pub where_is: WhereIsLocation,
    pub shoud_save: bool,
    pub elements: Vec<ElementInfo>,
    pub locations: Vec<LocationInfo>,
    pub path: PathBuf,
    pub module: Option<ModuleInfo>,
}

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

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