use alloc::{collections::BTreeMap, string::String, vec::Vec};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use serde_with::{
OneOrMany,
formats::{PreferMany, PreferOne},
serde_as,
};
pub type Gemspec = Specification;
#[serde_as]
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(default, tag = "@type")]
pub struct Specification<T = Metadata> {
#[serde(alias = "author")]
#[serde_as(as = "OneOrMany<_, PreferMany>")]
pub authors: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub bindir: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cert_chain: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub dependencies: Option<Vec<Dependency>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(alias = "emails", skip_serializing_if = "Vec::is_empty")]
#[serde_as(as = "OneOrMany<_, PreferOne>")]
pub email: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub executables: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extensions: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extensions_dir: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub extra_rdoc_files: Option<Vec<String>>,
pub files: Vec<String>,
pub homepage: Option<String>,
#[serde(alias = "license", skip_serializing_if = "Vec::is_empty")]
#[serde_as(as = "OneOrMany<_, PreferMany>")]
pub licenses: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<T>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub platform: Option<Platform>,
#[serde(skip_serializing_if = "Option::is_none")]
pub post_install_message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rdoc_options: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub require_paths: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_ruby_version: Option<Requirement>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required_rubygems_version: Option<Requirement>,
#[serde(skip_serializing_if = "Option::is_none")]
pub requirements: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rubygems_version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signing_key: Option<String>,
pub summary: String,
pub version: Version,
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct Dependency {
pub name: String,
pub requirement: Requirement,
pub r#type: String,
pub prerelease: bool,
pub version_requirements: Requirement,
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct Requirement {
pub requirements: Vec<(String, Version)>,
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct Version {
pub version: String,
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(rename_all(serialize = "lowercase", deserialize = "lowercase"))]
pub enum Platform {
#[default]
Ruby,
Current,
#[serde(untagged)]
Other(String),
}
#[derive(Clone, Debug, Default, Eq, Hash, PartialEq, Deserialize, Serialize)]
#[serde(default)]
pub struct Metadata {
#[serde(skip_serializing_if = "Option::is_none")]
pub bug_tracker_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub changelog_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub funding_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub homepage_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mailing_list_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_code_uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub wiki_uri: Option<String>,
#[serde(flatten, skip_serializing_if = "Map::is_empty")]
pub other: Map<String, Value>,
}