entertainarr-adapter-http 0.1.1

HTTP adapter for entertainarr
Documentation
crate::create_kind!(TaskKind, "tasks");

pub type TaskEntity = super::Entity<u64, TaskKind>;

#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TaskDocument {
    pub id: u64,
    #[serde(rename = "type")]
    pub kind: TaskKind,
    pub attributes: TaskAttributes,
}

#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TaskAttributes {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub after: Option<chrono::DateTime<chrono::Utc>>,
    pub status: TaskStatus,
    #[serde(flatten)]
    pub payload: TaskPayload,
    pub retries: u8,
    pub max_retries: u8,
    pub created_at: chrono::DateTime<chrono::Utc>,
    pub updated_at: chrono::DateTime<chrono::Utc>,
}

#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum TaskStatus {
    Pending,
    Running,
    Completed,
    Failed { message: Option<String> },
}

#[cfg_attr(feature = "facet", derive(facet::Facet))]
#[cfg_attr(feature = "facet", repr(C))]
#[derive(Clone, Debug, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
#[serde(tag = "targetKind", rename_all = "camelCase")]
pub enum TaskPayload {
    Podcast(super::podcast_task::PodcastTask),
    Noop,
}

#[cfg(test)]
mod tests {
    use chrono::DateTime;

    use crate::entity::task::{TaskAttributes, TaskDocument};

    #[test]
    fn should_serialize_task_document_pending_synchronize() {
        let task = TaskDocument {
            id: 1,
            kind: Default::default(),
            attributes: TaskAttributes {
                after: None,
                status: super::TaskStatus::Pending,
                payload: super::TaskPayload::Podcast(
                    crate::entity::podcast_task::PodcastTask::Synchronize { podcast_id: 42 },
                ),
                retries: 0,
                max_retries: 10,
                created_at: DateTime::from_timestamp(0, 0).unwrap(),
                updated_at: DateTime::from_timestamp(0, 0).unwrap(),
            },
        };
        let output = serde_json::to_string(&task).unwrap();
        assert_eq!(
            output,
            r#"{"id":1,"type":"tasks","attributes":{"status":{"type":"pending"},"targetKind":"podcast","method":"synchronize","targetId":42,"retries":0,"maxRetries":10,"createdAt":"1970-01-01T00:00:00Z","updatedAt":"1970-01-01T00:00:00Z"}}"#
        );
    }

    #[test]
    fn should_serialize_task_document_failed_synchronize() {
        let task = TaskDocument {
            id: 1,
            kind: Default::default(),
            attributes: TaskAttributes {
                after: None,
                status: super::TaskStatus::Failed {
                    message: Some("Oops".to_string()),
                },
                payload: super::TaskPayload::Podcast(
                    crate::entity::podcast_task::PodcastTask::SynchronizeAll,
                ),
                retries: 0,
                max_retries: 10,
                created_at: DateTime::from_timestamp(0, 0).unwrap(),
                updated_at: DateTime::from_timestamp(0, 0).unwrap(),
            },
        };
        let output = serde_json::to_string(&task).unwrap();
        assert_eq!(
            output,
            r#"{"id":1,"type":"tasks","attributes":{"status":{"type":"failed","message":"Oops"},"targetKind":"podcast","method":"synchronizeAll","retries":0,"maxRetries":10,"createdAt":"1970-01-01T00:00:00Z","updatedAt":"1970-01-01T00:00:00Z"}}"#
        );
    }

    #[test]
    fn should_serialize_task_document_running_noop() {
        let task = TaskDocument {
            id: 1,
            kind: Default::default(),
            attributes: TaskAttributes {
                after: None,
                status: super::TaskStatus::Running,
                payload: super::TaskPayload::Noop,
                retries: 0,
                max_retries: 10,
                created_at: DateTime::from_timestamp(0, 0).unwrap(),
                updated_at: DateTime::from_timestamp(0, 0).unwrap(),
            },
        };
        let output = serde_json::to_string(&task).unwrap();
        assert_eq!(
            output,
            r#"{"id":1,"type":"tasks","attributes":{"status":{"type":"running"},"targetKind":"noop","retries":0,"maxRetries":10,"createdAt":"1970-01-01T00:00:00Z","updatedAt":"1970-01-01T00:00:00Z"}}"#
        );
    }
}