spuz_piston 0.1.1

Minecraft json documents described in Rust
Documentation
use std::{
	collections::HashMap,
	fmt::{Debug, Display},
	ops::Deref,
	str::FromStr,
};

use serde::{Deserialize, Serialize};

use crate::{
	platform::NativeClassifier,
	rule::{ConditionalValue, Rule},
	Arr, BoxPath, Size, Str,
};

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum ListOrValue<T> {
	List(Arr<T>),
	Value(T),
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct AssetIndexRef {
	pub id: Str,
	pub url: Str,
	pub total_size: Size,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Artifact {
	pub path: BoxPath,
	pub sha1: Str,
	pub size: Size,
	pub url: Str,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(untagged)]
pub enum Argument {
	Plain(Str),
	Conditional(ConditionalValue<ListOrValue<Str>>),
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Arguments {
	pub game: Arr<Argument>,
	pub jvm: Arr<Argument>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Library {
	pub name: Str,
	pub downloads: Specifiers,
	pub rules: Option<Arr<Rule>>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Specifiers {
	pub artifact: Option<Artifact>,
	pub classifiers: Option<HashMap<NativeClassifier, Artifact>>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct DownloadItem {
	pub sha1: Str,
	pub size: Size,
	pub url: Str,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Downloads {
	pub client: DownloadItem,
	pub client_mappings: Option<DownloadItem>,
	pub server: DownloadItem,
	pub server_mappings: Option<DownloadItem>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LoggingFile {
	pub id: Str,
	pub sha1: Str,
	pub size: Size,
	pub url: Str,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ClientLogging {
	pub argument: Str,
	pub file: LoggingFile,
	pub r#type: Str,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Logging {
	pub client: ClientLogging,
}

impl Deref for Logging {
	type Target = ClientLogging;

	fn deref(&self) -> &Self::Target {
		&self.client
	}
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct Manifest {
	pub r#type: Str,
	pub id: Str,
	pub time: Str,
	pub release_time: Str,
	pub main_class: Str,
	pub assets: Str,
	pub asset_index: AssetIndexRef,
	pub libraries: Arr<Library>,
	pub arguments: Arguments,
	pub downloads: Downloads,
	pub logging: Logging,
}

impl FromStr for Manifest {
	type Err = serde_json::Error;

	fn from_str(s: &str) -> Result<Self, Self::Err> {
		serde_json::from_str(s)
	}
}

impl Display for Manifest {
	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
		serde_json::to_string(self).map_err(|_| std::fmt::Error).fmt(f)
	}
}