eureka-mmanager 0.4.0

An Actix actor collection for downloading manga, chapters, covers from Mangadex
Documentation
use std::sync::Arc;

use tokio::sync::RwLock;

use mangadex_api_types_rust::RelationshipType;
use serde::{Deserialize, Serialize};

use super::{HistoryBaseError, HistoryEntry, Insert, IsIn, Remove};

pub mod error;

pub(crate) type HBResult<T> = Result<T, HistoryBaseError>;

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct HistoryBase {
    history_list: Vec<uuid::Uuid>,
    data_type: RelationshipType,
}

impl From<HistoryBase> for Arc<RwLock<HistoryBase>> {
    fn from(val: HistoryBase) -> Self {
        Arc::new(RwLock::new(val))
    }
}

impl HistoryBase {
    pub fn new(data_type: RelationshipType) -> HistoryBase {
        HistoryBase {
            history_list: Vec::new(),
            data_type,
        }
    }
    pub fn get_history_list_mut(&mut self) -> &mut Vec<uuid::Uuid> {
        &mut (self.history_list)
    }
    pub fn get_history_list(&self) -> &Vec<uuid::Uuid> {
        &(self.history_list)
    }
    pub fn get_data_type_mut(&mut self) -> &mut RelationshipType {
        &mut (self.data_type)
    }
    pub fn get_data_type(&self) -> &RelationshipType {
        &(self.data_type)
    }
    pub fn is_this_type(&self, to_use_rel: RelationshipType) -> bool {
        self.data_type == to_use_rel
    }
}

impl IsIn<uuid::Uuid> for HistoryBase {
    type Output = Option<usize>;

    fn is_in(&self, to_use: uuid::Uuid) -> Self::Output {
        self.get_history_list()
            .iter()
            .position(|id| id.cmp(&to_use).is_eq())
    }
}

impl IsIn<HistoryEntry> for HistoryBase {
    type Output = HBResult<bool>;

    fn is_in(&self, to_use: HistoryEntry) -> Self::Output {
        if self.is_this_type(to_use.data_type) {
            Ok(self.is_in(to_use.id).is_some())
        } else {
            Err(HistoryBaseError::InvalidRelationship(to_use.data_type))
        }
    }
}

impl Insert<uuid::Uuid> for HistoryBase {
    type Output = HBResult<()>;
    fn insert(&mut self, input: uuid::Uuid) -> Self::Output {
        let result = <Self as IsIn<uuid::Uuid>>::is_in(self, input);
        if result.is_none() {
            self.get_history_list_mut().push(input);
            Ok(())
        } else {
            Err(HistoryBaseError::AlreadyExists(input))
        }
    }
}

impl Insert<HistoryEntry> for HistoryBase {
    type Output = HBResult<()>;

    fn insert(&mut self, input: HistoryEntry) -> Self::Output {
        let result = <Self as IsIn<HistoryEntry>>::is_in(self, input)?;
        if !result {
            self.get_history_list_mut().push(input.id);
        } else {
            return Err(HistoryBaseError::AlreadyExists(input.id));
        }
        Ok(())
    }
}

impl Remove<uuid::Uuid> for HistoryBase {
    type Output = HBResult<()>;

    fn remove(&mut self, input: uuid::Uuid) -> Self::Output {
        let position = <Self as IsIn<uuid::Uuid>>::is_in(self, input)
            .ok_or(HistoryBaseError::NotFound(input))?;
        self.get_history_list_mut().remove(position);
        Ok(())
    }
}

impl Remove<HistoryEntry> for HistoryBase {
    type Output = HBResult<()>;
    fn remove(&mut self, input: HistoryEntry) -> Self::Output {
        let result = self.is_this_type(input.data_type);
        if result {
            <Self as Remove<uuid::Uuid>>::remove(self, input.id)
        } else {
            Err(HistoryBaseError::InvalidRelationship(input.data_type))
        }
    }
}

impl IntoIterator for HistoryBase {
    type Item = uuid::Uuid;

    type IntoIter = std::vec::IntoIter<Self::Item>;

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