use anyhow::bail;
use serde::{Deserialize, Serialize};
use tokio_postgres::Row;

use crate::Error;

#[derive(Deserialize, Serialize, Debug)]
pub struct Exchange {
    pub exchange_id: ExchangeId,
    pub name: String,
}

impl TryFrom<&Row> for Exchange {
    type Error = Error;

    fn try_from(value: &Row) -> Result<Self, Self::Error> {
        let id: i64 = value.try_get("id")?;
        let name: String = value.try_get("name")?;

        Ok(Exchange {
            exchange_id: id.try_into()?,
            name: name,
        })
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub enum ExchangeId {
    US = 1,
}

impl ToString for ExchangeId {
    fn to_string(&self) -> String {
        match self {
            ExchangeId::US => "US".into(),
        }
    }
}

impl TryFrom<i64> for ExchangeId {
    type Error = anyhow::Error;

    fn try_from(value: i64) -> Result<Self, Self::Error> {
        let v = match value {
            1 => ExchangeId::US,
            _ => bail!("couldn't map {value} to exchange id"),
        };
        Ok(v)
    }
}
