use core::fmt; use chrono::{DateTime, Utc}; use serde::{de::Visitor, Deserialize}; use sha1_smol::Digest; #[derive(Deserialize, Debug)] pub struct LatestVersions { pub release: String, pub snapshot: String } #[derive(Debug, Clone)] pub enum VersionType { Snapshot, Release, OldBeta, OldAlpha, Other(String) } struct VersionTypeVisitor; impl<'de> Visitor<'de> for VersionTypeVisitor { type Value = VersionType; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a Minecraft release type") } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { match v { "snapshot" => Ok(VersionType::Snapshot), "release" => Ok(VersionType::Release), "old_beta" => Ok(VersionType::OldBeta), "old_alpha" => Ok(VersionType::OldAlpha), _ => Ok(VersionType::Other(v.to_owned())) } } } impl<'de> Deserialize<'de> for VersionType { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de> { deserializer.deserialize_string(VersionTypeVisitor) } } // https://piston-meta.mojang.com/mc/game/version_manifest_v2.json #[derive(Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct VersionManifestVersion { pub id: String, #[serde(rename = "type")] pub version_type: VersionType, pub url: String, pub time: DateTime, pub release_time: DateTime, pub sha1: Digest, pub compliance_level: u32 } #[derive(Deserialize, Debug)] pub struct VersionManifest { pub latest: LatestVersions, pub versions: Vec }