metrom-commons 1.23.0

A collection of common utilities for Metrom-related projects.
Documentation
use std::{fmt::Display, str::FromStr};

use postgres_types::{FromSql, ToSql};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use utoipa::ToSchema;

#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, PartialEq, Eq, ToSchema)]
#[serde(rename_all = "kebab-case")]
pub enum Amm {
    UniswapV3,
    AlgebraIntegral,
    Croc,
    Curve,
    Carbon,
    Nuri,
    Velodrome,
}

#[derive(Error, Debug)]
pub enum AmmFromStringError {
    #[error("String {0} cannot be converted to a valid AMM")]
    Invalid(String),
}

impl FromStr for Amm {
    type Err = AmmFromStringError;

    fn from_str(value: &str) -> Result<Self, Self::Err> {
        match value {
            "uniswap-v3" => Ok(Self::UniswapV3),
            "algebra-integral" => Ok(Self::AlgebraIntegral),
            "croc" => Ok(Self::Croc),
            "curve" => Ok(Self::Curve),
            "carbon" => Ok(Self::Carbon),
            "nuri" => Ok(Self::Nuri),
            "velodrome" => Ok(Self::Velodrome),
            _ => Err(AmmFromStringError::Invalid(value.to_string())),
        }
    }
}

impl Display for Amm {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Amm::UniswapV3 => write!(f, "uniswap-v3"),
            Amm::AlgebraIntegral => write!(f, "algebra-integral"),
            Amm::Croc => write!(f, "croc"),
            Amm::Curve => write!(f, "curve"),
            Amm::Carbon => write!(f, "carbon"),
            Amm::Nuri => write!(f, "nuri"),
            Amm::Velodrome => write!(f, "velodrome"),
        }
    }
}

impl<'a> FromSql<'a> for Amm {
    fn from_sql(
        ty: &postgres_types::Type,
        raw: &'a [u8],
    ) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
        Ok(<String as FromSql>::from_sql(ty, raw)?.parse()?)
    }

    postgres_types::accepts!(VARCHAR);
}

impl ToSql for Amm {
    fn to_sql(
        &self,
        ty: &postgres_types::Type,
        out: &mut alloy::primitives::bytes::BytesMut,
    ) -> Result<postgres_types::IsNull, Box<dyn std::error::Error + Sync + Send>>
    where
        Self: Sized,
    {
        self.to_string().to_sql(ty, out)
    }

    postgres_types::accepts!(VARCHAR);

    postgres_types::to_sql_checked!();
}