//! Notices
//!
//! Notices are the way relayers send errors with their description to clients
//!
//! This may happen when client makes mistakes at the protocol level
use crate::common::SerializeDeserialize;
use serde_json::Value;
use std::{collections::VecDeque, ops::Deref};

/// Notices are errors
#[derive(Clone, Debug)]
pub struct Notice(pub String);

impl Deref for Notice {
    type Target = str;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl SerializeDeserialize for Notice {
    fn get_tag() -> &'static str {
        "NOTICE"
    }

    fn serialize(&self) -> Result<Vec<Value>, String> {
        Ok(vec![
            Value::String(Self::get_tag().to_owned()),
            Value::String(self.0.to_owned()),
        ])
    }

    fn deserialize(args: VecDeque<Value>) -> Result<Self, String> {
        if args.is_empty() {
            return Err("Invalid length".to_owned());
        }
        let message = args[0]
            .as_str()
            .ok_or_else(|| "Invalid message, expected string".to_owned())?
            .to_owned();
        Ok(Notice(message))
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::Response;

    #[test]
    fn parse() {
        let json = r#"["NOTICE", "test"]"#;
        let message: Response = serde_json::from_str(json).expect("message");
        assert!(message.as_notice().is_some());
    }

    #[test]
    fn serialize() {
        let notice = Notice("test".to_owned());
        let m: Response = notice.into();
        assert_eq!(
            r#"["NOTICE","test"]"#,
            serde_json::to_string(&m).expect("valid json")
        );
    }
}
