use serde::ser::SerializeStruct;
use serde::{Serialize, Serializer};

pub enum DatabaseError {
    InsertError,
    InsertGetError,
    NotFound,
}

impl DatabaseError {
    fn to_code(&self) -> u32 {
        match self {
            DatabaseError::NotFound => 404,
            _ => 500
        }
    }
}

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

impl From<&DatabaseError> for String {
    fn from(err: &DatabaseError) -> Self {
        match err {
            DatabaseError::InsertError => String::from("error inserting into database"),
            DatabaseError::InsertGetError => {
                String::from("error retrieving new entry from database (your entry was saved)")
            }
            DatabaseError::NotFound => String::from("model was not found in database")
        }
    }
}