use std::collections::HashSet; use addonscript_versioning::{Version, VersionRestriction}; use enums::{Side, ArgumentMode}; use error::Error; use serde::{Deserialize, Serialize}; use url::Url; pub use self::{ enums::{Flag, InstallAction}, meta::*, }; pub mod api; pub mod error; pub mod enums; pub mod meta; #[derive(Debug, Serialize, Deserialize)] pub struct Manifest { pub addonscript: AddonScript, pub id: String, pub namespace: String, pub version: Version, #[serde(default)] pub files: Vec, #[serde(default)] pub relations: Vec, pub flags: Flags, #[serde(default)] pub repositories: Vec, #[serde(default)] pub instance: bool, #[serde(default)] #[deprecated] pub use_builder: bool, #[serde(default)] pub patches: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub meta: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct VersionlessManifest { #[serde(skip_serializing_if = "Option::is_none")] pub addonscript: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct AddonScript { pub version: u8, } impl Default for AddonScript { fn default() -> Self { Self { version: 2 } } } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct AddonDescriptor { pub id: String, pub namespace: String, #[serde(skip_serializing_if = "Option::is_none")] pub version: Option, } #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Repository { pub namespace: String, pub instances: Vec, } #[derive(Debug, Serialize, Deserialize)] pub struct Relation { pub id: String, #[serde(skip_serializing_if = "Option::is_none")] pub namespace: Option, pub version: VersionRestriction, #[serde(skip_serializing_if = "Option::is_none")] pub repositories: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub flags: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct File { pub qualifier: String, pub link: Vec, #[serde(default)] pub install: Vec, #[serde(skip_serializing_if = "Option::is_none")] pub flags: Option, #[serde(skip_serializing_if = "Option::is_none")] pub hashes: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct Hashes { #[serde(skip_serializing_if = "Option::is_none")] pub sha1: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct Install { pub action: InstallAction, #[serde(default)] pub args: Vec, #[serde(default)] pub side: Side, } #[derive(Debug, Serialize, Deserialize)] pub struct Flags { #[serde(skip_serializing_if = "Option::is_none")] pub client: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub server: Option>, #[serde(skip_serializing_if = "Option::is_none")] pub both: Option>, } #[derive(Debug, Serialize, Deserialize)] pub struct Patch { pub side: Side, #[serde(skip_serializing_if = "Option::is_none")] pub main_class: Option, #[serde(default)] pub arguments: Vec, #[serde(default)] pub jvm_arguments: Vec, #[serde(default)] pub replace_jvm_arguments: bool, #[serde(skip_serializing_if = "Option::is_none")] pub java_version: Option, } #[derive(Debug, Serialize, Deserialize)] pub struct GameArgument { pub mode: ArgumentMode, #[serde(skip_serializing_if = "Option::is_none")] pub key: Option, #[serde(skip_serializing_if = "Option::is_none")] pub value: Option, #[serde(skip_serializing_if = "Option::is_none")] pub raw: Option, } impl VersionlessManifest { pub fn get_version(&self) -> u8 { match &self.addonscript { Some(addonscript) => addonscript.version, None => 1, } } pub fn is_version_valid(&self) -> bool { self.get_version() == 2 } } impl Flags { pub fn has_client_flag(&self, flag: &Flag) -> bool { if let Some(flags) = &self.client { if flags.contains(flag) { return true; } } if let Some(flags) = &self.both { if flags.contains(flag) { return true; } } false } pub fn has_server_flag(&self, flag: &Flag) -> bool { if let Some(flags) = &self.server { if flags.contains(flag) { return true; } } if let Some(flags) = &self.both { if flags.contains(flag) { return true; } } false } } impl Manifest { pub fn get_file(&self, qualifier: String) -> Option<&File> { for file in &self.files { if file.qualifier == qualifier { return Some(file); } } None } } impl GameArgument { pub fn format_argument(&self) -> Result { if let Some(raw) = &self.raw { Ok(raw.clone()) } else { let key = self.key.clone().ok_or(Error::InvalidFormat)?; let value = self.value.clone().unwrap_or_else(|| "".to_string()); Ok(format!("--{} {}", key, value)) } } }