use actix_web::http::StatusCode;
use actix_web::HttpResponse;
use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};

#[derive(Debug)]
pub enum HandlerError {
    BadUid,
    ProtectedSchedule,
}

impl HandlerError {
    fn get_code(&self) -> StatusCode {
        match self {
            HandlerError::BadUid => StatusCode::BAD_REQUEST,
            HandlerError::ProtectedSchedule => StatusCode::FORBIDDEN,
        }
    }
}

impl Serialize for HandlerError {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut s = serializer.serialize_struct("error", 2)?;
        s.serialize_field("code", &self.get_code().as_u16())?;
        s.serialize_field("description", &String::from(self))?;
        s.end()
    }
}

impl From<&HandlerError> for String {
    fn from(err: &HandlerError) -> Self {
        match err {
            HandlerError::BadUid => String::from("the uid is in a bad format"),
            HandlerError::ProtectedSchedule => String::from("the targeted schedule is protected"),
        }
    }
}

impl From<HandlerError> for HttpResponse {
    fn from(err: HandlerError) -> Self {
        HttpResponse::build(err.get_code()).json(err)
    }
}