use crate::error::ApiError;
use std::convert::{From, TryFrom};

#[derive(Copy, Clone)]
pub enum EntryStatus {
    Read,
    Unread,
    Removed,
}

impl From<EntryStatus> for &str {
    fn from(item: EntryStatus) -> Self {
        match item {
            EntryStatus::Read => "read",
            EntryStatus::Unread => "unread",
            EntryStatus::Removed => "removed",
        }
    }
}

impl TryFrom<&str> for EntryStatus {
    type Error = ApiError;

    fn try_from(item: &str) -> Result<Self, ApiError> {
        let parsed = match item {
            "read" => EntryStatus::Read,
            "unread" => EntryStatus::Unread,
            "removed" => EntryStatus::Removed,
            _ => return Err(ApiError::Parse),
        };
        Ok(parsed)
    }
}

#[derive(Copy, Clone)]
pub enum OrderBy {
    ID,
    Status,
    PublishedAt,
    CategoryTitle,
    CategoryID,
}

impl From<OrderBy> for &str {
    fn from(item: OrderBy) -> Self {
        match item {
            OrderBy::ID => "id",
            OrderBy::Status => "status",
            OrderBy::PublishedAt => "published_at",
            OrderBy::CategoryTitle => "category_title",
            OrderBy::CategoryID => "category_id",
        }
    }
}

impl TryFrom<&str> for OrderBy {
    type Error = ApiError;

    fn try_from(item: &str) -> Result<Self, ApiError> {
        let parsed = match item {
            "id" => OrderBy::ID,
            "status" => OrderBy::Status,
            "published_at" => OrderBy::PublishedAt,
            "category_title" => OrderBy::CategoryTitle,
            "category_id" => OrderBy::CategoryID,
            _ => return Err(ApiError::Parse),
        };
        Ok(parsed)
    }
}

#[derive(Copy, Clone)]
pub enum OrderDirection {
    Asc,
    Desc,
}

impl From<OrderDirection> for &str {
    fn from(item: OrderDirection) -> Self {
        match item {
            OrderDirection::Asc => "asc",
            OrderDirection::Desc => "desc",
        }
    }
}

impl TryFrom<&str> for OrderDirection {
    type Error = ApiError;

    fn try_from(item: &str) -> Result<Self, ApiError> {
        let parsed = match item {
            "asc" => OrderDirection::Asc,
            "desc" => OrderDirection::Desc,
            _ => return Err(ApiError::Parse),
        };
        Ok(parsed)
    }
}
