use serde::{Deserialize, Serialize};
use std::str::FromStr;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ClientCode {
BU,
EJ,
EG,
GE,
GR,
LH,
LS,
NM,
NB,
TK,
PM,
RH,
}
impl ClientCode {
pub const fn as_str(&self) -> &'static str {
match self {
Self::BU => "BU",
Self::EJ => "EJ",
Self::EG => "EG",
Self::GE => "GE",
Self::GR => "GR",
Self::LH => "LH",
Self::LS => "LS",
Self::NM => "NM",
Self::NB => "NB",
Self::TK => "TK",
Self::PM => "PM",
Self::RH => "RH",
}
}
pub const fn client_name(&self) -> &'static str {
match self {
Self::BU => "Besu",
Self::EJ => "EthereumJS",
Self::EG => "Erigon",
Self::GE => "Geth",
Self::GR => "Grandine",
Self::LH => "Lighthouse",
Self::LS => "Lodestar",
Self::NM => "Nethermind",
Self::NB => "Nimbus",
Self::TK => "Teku",
Self::PM => "Prysm",
Self::RH => "Reth",
}
}
}
impl FromStr for ClientCode {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"BU" => Ok(Self::BU),
"EJ" => Ok(Self::EJ),
"EG" => Ok(Self::EG),
"GE" => Ok(Self::GE),
"GR" => Ok(Self::GR),
"LH" => Ok(Self::LH),
"LS" => Ok(Self::LS),
"NM" => Ok(Self::NM),
"NB" => Ok(Self::NB),
"TK" => Ok(Self::TK),
"PM" => Ok(Self::PM),
"RH" => Ok(Self::RH),
s => Err(s.to_string()),
}
}
}
impl std::fmt::Display for ClientCode {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientVersionV1 {
pub code: ClientCode,
pub name: String,
pub version: String,
pub commit: String,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn client_id_serde() {
let s = r#"{"code":"RH","name":"Reth","version":"v1.10.8","commit":"fa4ff922"}"#;
let v: ClientVersionV1 = serde_json::from_str(s).unwrap();
assert_eq!(v.code, ClientCode::RH);
assert_eq!(v.name, "Reth");
assert_eq!(serde_json::to_string(&v).unwrap(), s);
}
}