//! UTF8 字符串转为字符
#![allow(dead_code)]

use crate::{DecodeError, DecodeTrait, EncodeTrait};

extern crate urlencoding;

/// url 编码转换
#[derive(Debug, Clone)]
pub struct URLCode(String);

impl Into<String> for URLCode {
    fn into(self) -> String {
        self.0
    }
}

pub fn vec_ref<'a>(s: &'a String) -> Vec<&'a str> {
    let temp = s.split("");
    temp.filter(|&s| s != "").collect::<Vec<&str>>()
}

impl URLCode {
    pub fn try_decode(&self) -> Result<String, DecodeError> {
        Self::decode(self.get_inner())
    }

    pub fn get_inner(&self) -> String {
        self.0.clone()
    }

    pub fn vec_ref(&self) -> Vec<&str> {
        vec_ref(&self.0)
    }
}

impl From<&str> for URLCode {
    fn from(s: &str) -> Self {
        URLCode(Self::encode(s))
    }
}

impl From<String> for URLCode {
    fn from(s: String) -> Self {
        URLCode(Self::encode(s))
    }
}

impl EncodeTrait<&str> for URLCode {
    fn encode(s: &str) -> String {
        urlencoding::encode(s)
    }
}

impl EncodeTrait<String> for URLCode {
    fn encode(s: String) -> String {
        urlencoding::encode(&s)
    }
}

impl DecodeTrait<&str> for URLCode {
    fn decode(s: &str) -> Result<String, DecodeError> {
        urlencoding::decode(s).map_err(|_| DecodeError(s.to_string()))
    }
}

impl DecodeTrait<String> for URLCode {
    fn decode(s: String) -> Result<String, DecodeError> {
        urlencoding::decode(&s).map_err(|_| DecodeError(s.to_string()))
    }
}

#[cfg(test)]
mod test {

    use super::*;

    #[test]
    fn test_escape_code_encode() {
        let test = URLCode::encode("test测试");
        assert_eq!("test%E6%B5%8B%E8%AF%95".to_string(), test);
    }

    #[test]
    fn test_escape_code_decode() {
        let test = URLCode::decode("test%E6%B5%8B%E8%AF%95");
        assert_eq!(test, Ok("test测试".to_string()));
    }
}
