eureka-mmanager 0.3.3

An Actix actor collection for downloading manga, chapters, covers from Mangadex
Documentation
use actix::prelude::*;
use dev::ToEnvelope;

use super::MailBoxResult;

use crate::{
    download::{
        messages::{
            CancelTaskMessage, StartDownload, SubcribeMessage, TaskStateMessage,
            TaskSubscriberMessages, WaitForFinishedMessage,
        },
        state::{TaskState, WaitForFinished},
    },
    recipients::MaybeWeakRecipient,
};

pub trait Cancelable: Actor {
    fn cancel(&mut self, ctx: &mut Self::Context);
}

pub trait Download: Actor {
    fn download(&mut self, ctx: &mut Self::Context);
}

pub trait State: Actor
where
    Self::State: Into<TaskState> + Send,
{
    type State;
    fn state(&self) -> TaskState {
        self.inner_state().into()
    }
    fn inner_state(&self) -> Self::State;
}

pub trait Subscribe: State {
    fn subscribe(&mut self, subscriber: MaybeWeakRecipient<TaskSubscriberMessages<Self::State>>);
}

pub trait CanBeWaited: State {
    type Ok;
    type Loading;
    fn wait(&mut self) -> WaitForFinished<Self::Ok, Self::Loading>;
}

pub trait AsyncCancelable: Sync {
    fn cancel(&self) -> impl std::future::Future<Output = MailBoxResult<()>> + Send;
}

impl<A> AsyncCancelable for Addr<A>
where
    A: Handler<CancelTaskMessage> + Cancelable,
    <A as actix::Actor>::Context:
        actix::dev::ToEnvelope<A, crate::download::messages::CancelTaskMessage>,
{
    async fn cancel(&self) -> MailBoxResult<()> {
        self.send(CancelTaskMessage).await
    }
}

pub trait AsyncDownload: Sync {
    fn download(&self) -> impl std::future::Future<Output = MailBoxResult<()>> + Send;
}

impl<A> AsyncDownload for Addr<A>
where
    A: Handler<StartDownload> + Download,
    <A as Actor>::Context: ToEnvelope<A, StartDownload>,
{
    async fn download(&self) -> MailBoxResult<()> {
        self.send(StartDownload).await
    }
}

pub trait AsyncState: Sync {
    type State: Send;
    fn state(&self) -> impl std::future::Future<Output = MailBoxResult<TaskState>> + Send;
}

impl<A> AsyncState for Addr<A>
where
    A: Handler<TaskStateMessage> + State,
    <A as Actor>::Context: ToEnvelope<A, TaskStateMessage>,
{
    type State = <A as State>::State;
    async fn state(&self) -> MailBoxResult<TaskState> {
        self.send(TaskStateMessage).await
    }
}

pub trait AsyncSubscribe: AsyncState {
    fn subscribe(
        &self,
        subscriber: MaybeWeakRecipient<TaskSubscriberMessages<Self::State>>,
    ) -> impl std::future::Future<Output = MailBoxResult<()>> + Send;
}

impl<A> AsyncSubscribe for Addr<A>
where
    A: Handler<SubcribeMessage<<A as State>::State>>
        + Subscribe
        + Handler<TaskStateMessage>
        + State,
    <A as State>::State: Send + Sync,
    <A as Actor>::Context:
        ToEnvelope<A, SubcribeMessage<<A as State>::State>> + ToEnvelope<A, TaskStateMessage>,
{
    async fn subscribe(
        &self,
        subscriber: MaybeWeakRecipient<TaskSubscriberMessages<Self::State>>,
    ) -> MailBoxResult<()> {
        self.send(SubcribeMessage(subscriber)).await
    }
}

pub trait AsyncCanBeWaited: AsyncState {
    type Ok;
    type Loading;
    fn wait(
        &mut self,
    ) -> impl std::future::Future<Output = MailBoxResult<WaitForFinished<Self::Ok, Self::Loading>>> + Send;
}

impl<A> AsyncCanBeWaited for Addr<A>
where
    A: Handler<SubcribeMessage<<A as State>::State>>
        + Subscribe
        + Handler<TaskStateMessage>
        + State
        + CanBeWaited
        + Handler<WaitForFinishedMessage<<A as CanBeWaited>::Ok, <A as CanBeWaited>::Loading>>,
    <A as State>::State: Send + Sync,
    <A as CanBeWaited>::Loading: Send + Sync,
    <A as CanBeWaited>::Ok: Send + Sync,
    <A as Actor>::Context: ToEnvelope<A, SubcribeMessage<<A as State>::State>>
        + ToEnvelope<A, TaskStateMessage>
        + ToEnvelope<A, WaitForFinishedMessage<<A as CanBeWaited>::Ok, <A as CanBeWaited>::Loading>>,
{
    type Loading = <A as CanBeWaited>::Loading;
    type Ok = <A as CanBeWaited>::Ok;
    async fn wait(&mut self) -> MailBoxResult<WaitForFinished<Self::Ok, Self::Loading>> {
        self.send(WaitForFinishedMessage::<
            <A as CanBeWaited>::Ok,
            <A as CanBeWaited>::Loading,
        >::new())
            .await
    }
}