use serde::{Deserialize, Serialize};
use crate::MicroversusError;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RoundConfig;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct WorldDetailsTmpl<Metadata, Config> {
pub slug: String,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub round_id: Option<u32>,
pub metadata: Metadata,
pub config: Config,
#[serde(skip_serializing_if = "Option::is_none")]
pub round_start: Option<u32>,
}
pub type RawWorldDetails = WorldDetailsTmpl<Option<String>, Option<String>>;
pub type WorldDetails = WorldDetailsTmpl<Option<serde_json::Value>, Option<RoundConfig>>;
impl TryFrom<RawWorldDetails> for WorldDetails {
type Error = MicroversusError;
fn try_from(value: RawWorldDetails) -> Result<Self, Self::Error> {
let metadata: Option<serde_json::Value> = value
.metadata
.map(|t| serde_json::from_str(&t))
.transpose()?;
let config: Option<RoundConfig> =
value.config.map(|t| serde_json::from_str(&t)).transpose()?;
Ok(WorldDetails {
slug: value.slug.clone(),
name: value.name.clone(),
round_id: value.round_id,
metadata,
config,
round_start: value.round_start,
})
}
}
impl TryFrom<&RawWorldDetails> for WorldDetails {
type Error = MicroversusError;
fn try_from(value: &RawWorldDetails) -> Result<Self, Self::Error> {
WorldDetails::try_from(value.clone())
}
}