use serde::{Deserialize,Serialize,Deserializer};
//use sqlx::{sqlite::SqlitePool, Row, Sqlite};
// use sqlx::{
//     FromRow,
//     decode::Decode,
//     any::{AnyRow, AnyValueRef},
//     database::{
//         Database,
//         HasValueRef,
//     },
//     Row,
// //    Error, 
// };
// use std::error::Error;
// use std::str::FromStr;

//use super::User;

// #[derive(sqlx::FromRow)][derive(sqlx::Type)]
//#[derive(sqlx::Type)]
//#[sqlx(type_name = "userstatus_type")]
// #[derive(sqlx::FromRow)]
//#[sqlx(display_fromstr)]
#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
pub enum UserStatus {
    Created,
    Active,
    Pending,
    Lock,
    Unknown,
}
impl UserStatus {
    #[allow(dead_code)]
    pub fn from_str(status: &str) -> Self {
        match status {
            "created"|"Created" => UserStatus::Created,
            "active"|"Active" => UserStatus::Active,
            "pending"|"Pending" => UserStatus::Pending,
            "lock"|"Lock" => UserStatus::Lock,
            _ => UserStatus::Unknown,
        }
    }
}
impl std::fmt::Display for UserStatus {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            UserStatus::Created => write!(f,"Created"),
            UserStatus::Active => write!(f,"Active"),
            UserStatus::Pending => write!(f,"Pending"),
            UserStatus::Lock => write!(f,"Lock"),
            UserStatus::Unknown => write!(f,"Unknown"),
        }
    }
}

impl Default for UserStatus {
    fn default() -> Self {
       UserStatus::Unknown
    }
}
#[allow(dead_code)]
pub fn deserialize_user_status<'de, D>(deserializer: D) -> Result<UserStatus, D::Error>
where D: Deserializer<'de> {
    let buf = String::deserialize(deserializer)?;
    Ok(UserStatus::from_str(&buf))
}
// impl sqlx::Type<sqlx::Any> for UserStatus {
//     fn type_info() -> sqlx::any::AnyTypeInfo {
//         //let res: sqlx::any::AnyTypeInfo = String::type_info();
// let res = <str as sqlx::Type<sqlx::Any>>::type_info();
//        //  let res = sqlx::any::AnyTypeInfo::default(); //  String::type_info();
//         res 
//         // String::type_info()
//     }

//     // fn compatible(ty: &<sqlx::Any>::AnyTypeInfo) -> bool {
//     //     *ty == Self::type_info()
//     // }
// }
/* 
impl sqlx::Type<sqlx::Sqlite> for UserStatus {
    fn type_info() -> sqlx::sqlite::SqliteTypeInfo {
        let t = String::type_info();
        t
    }
}
impl sqlx::Type<sqlx::Mssql> for UserStatus {
    fn type_info() -> sqlx::mssql::MssqlTypeInfo {
        String::type_info()
    }
}
impl sqlx::Type<sqlx::MySql> for UserStatus {
    fn type_info() -> sqlx::mysql::MySqlTypeInfo {
        String::type_info()
    }
}
impl sqlx::Type<sqlx::Postgres> for UserStatus {
    fn type_info() -> sqlx::postgres::PgTypeInfo {
        String::type_info()
    }
}

impl<'q> sqlx::Encode<'q, sqlx::Any> for UserStatus {
    fn encode_by_ref(
        &self,
        args: &mut sqlx::any::AnyArgumentBuffer<'q>,
    ) -> sqlx::encode::IsNull {
        self.encode_by_ref(args)
    }
}
*/


/*
impl<'r> sqlx::Decode<'r, sqlx::Any> for UserStatus {
    fn decode(
       //  value: <DB as HasValueRef<'r>>::AnyValueRef,
        value: sqlx::any::AnyValueRef<'r>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        //let string = value.     try_decode()?;
        //let string = <&str as Decode<AnyValueRef>>::decode(value)?;
        let v = value.to_owned();
        let string = value.parse()?;
        let value = UserStatus::from_str(&string);
        Ok(value)
    }
}


impl<'r, DB: Database> Decode<'r, DB> for UserStatus
where
    // we want to delegate some of the work to string decoding so let's make sure strings
    // are supported by the database
    &'r str: Decode<'r, DB>
{
    fn decode(
        value: <DB as HasValueRef<'r>>::ValueRef,
    ) -> Result<UserStatus, Box<dyn Error + 'static + Send + Sync>> {
        // the interface of ValueRef is largely unstable at the moment
        // so this is not directly implementable
        // however, you can delegate to a type that matches the format of the type you want
        // to decode (such as a UTF-8 string)
        let val = <&str as Decode<DB>>::decode(value)?;
        // now you can parse this into your type (assuming there is a `FromStr`)
        //Ok(value.parse()?)
        Ok(UserStatus::from_str(&val))
    }
}
*/

/* 
impl<'r> Decode<'r, sqlx::Any> for UserStatus {
    fn decode(
        value: sqlx::any::AnyValueRef<'r>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        //let mut decoder = <dyn sqlx::any::AnyDecode>::new(value)?;
        //let string = decoder.try_decode::<String>()?;
        //let username = decoder.try_decode::<String>()?;
        //let photo = decoder.try_decode::<Option<String>>()?;
        let string = <&str as Decode<sqlx::Any>>::decode(value)?;
        let value = UserStatus::from_str(&string);
        Ok(value)
    }
}
impl<'r> Decode<'r, sqlx::Sqlite> for UserStatus {
    fn decode(
        value: sqlx::sqlite::SqliteValueRef<'r>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        let string = <&str as Decode<sqlx::Sqlite>>::decode(value)?;
        let value = UserStatus::from_str(string);
        Ok(value)
    }
}
// impl<'r> Decode<'r, sqlx::Mssql> for UserStatus {
//     fn decode(
//         value: sqlx::mssql::MssqlValueRef<'r>,
//     ) -> Result<UserStatus, Box<dyn Error + 'static + Send + Sync>> { 
//     //) -> Result<Self, sqlx::error::BoxDynError> {
//         let string = <&str as Decode<sqlx::Mssql>>::decode(value)?;
//         let value = UserStatus::from_str(string);
//         Ok(value)
//     }
// }
impl<'r> Decode<'r, sqlx::MySql> for UserStatus {
    fn decode(
        value: sqlx::mysql::MySqlValueRef<'r>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        let string = <&str as Decode<sqlx::MySql>>::decode(value)?;
        let value = UserStatus::from_str(string);
        Ok(value)
    }
}
impl<'r> Decode<'r, sqlx::Postgres> for UserStatus {
    fn decode(
        value: sqlx::postgres::PgValueRef<'r>,
    ) -> Result<Self, sqlx::error::BoxDynError> {
        //let mut decoder = sqlx::postgres::types::PgRecordDecoder::new(value)?;
        ////let username = decoder.try_decode::<String>()?;
        //let string = decoder.try_decode::<String>()?;
        let string = <&str as Decode<sqlx::Postgres>>::decode(value)?;
        let value = UserStatus::from_str(string);
        Ok(value)
    }
}

impl FromRow<'_, AnyRow> for UserStatus {
    fn from_row(row: &AnyRow) -> sqlx::Result<Self> {
        let v: String = row.try_get("status")?;
        Ok(
           UserStatus::from_str(&v)
        )
    }
}
impl FromStr for UserStatus {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(UserStatus::from_str(s))
    }
}

*/