use schemars::JsonSchema;
use serde::Deserialize;
use serde::de::Deserializer;
use super::de::{Located, Loose, Map, OneOf, UnknownKeys};
#[derive(Deserialize, JsonSchema)]
#[schemars(title = "DRE dependencies", deny_unknown_fields)]
pub struct DependenciesFile {
#[serde(default)]
#[schemars(schema_with = "plugins")]
pub plugins: Option<PluginsSection>,
#[serde(default)]
pub extensions: Vec<ExtensionEntry>,
pub packages: Option<Located<Loose<Vec<Loose<Package>>>>>,
}
#[derive(Clone, Deserialize, JsonSchema)]
#[serde(deny_unknown_fields)]
#[schemars(deny_unknown_fields)]
pub struct ExtensionEntry {
pub name: String,
pub version: String,
#[serde(default)]
pub accept_license: Option<String>,
}
#[derive(Deserialize)]
pub struct PluginsKey {
pub plugins: Option<PluginsSection>,
}
pub type PluginsSection = Located<Loose<OneOf<Vec<Located<Loose<PluginItem>>>, Map<serde_json::Value>>>>;
pub type PluginItem = OneOf<PackageName, OneOf<PinnedVersion, PluginEntry>>;
#[derive(Deserialize, JsonSchema)]
#[serde(transparent)]
#[schemars(inline)]
pub struct PackageName(pub String);
#[derive(JsonSchema)]
#[schemars(inline, extend("additionalProperties" = true, "minProperties" = 1, "maxProperties" = 1))]
pub struct PinnedVersion {
#[schemars(skip)]
pub name: Located<String>,
#[schemars(skip)]
pub version: serde_json::Value,
}
impl<'de> Deserialize<'de> for PinnedVersion {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let m = Map::<serde_json::Value>::deserialize(d)?;
match <[_; 1]>::try_from(m.0) {
Ok([(name, version)]) if name.value != "name" => Ok(PinnedVersion { name, version }),
_ => Err(serde::de::Error::custom("not a single `name: version` pair")),
}
}
}
#[derive(Deserialize, JsonSchema)]
#[schemars(deny_unknown_fields, inline)]
pub struct PluginEntry {
#[schemars(with = "String")]
pub name: Loose<String>,
#[serde(default)]
#[schemars(with = "String")]
pub version: Option<serde_json::Value>,
#[serde(default)]
#[schemars(with = "String")]
pub github: Option<serde_json::Value>,
#[serde(default)]
#[schemars(with = "String")]
pub local: Option<serde_json::Value>,
#[serde(default)]
#[schemars(with = "String")]
pub registry: Option<serde_json::Value>,
#[serde(rename = "$unknown", default)]
#[schemars(skip)]
pub unknown: UnknownKeys,
}
#[derive(Deserialize, JsonSchema)]
#[schemars(rename = "package", deny_unknown_fields)]
#[schemars(extend("oneOf" = [{"required": ["git", "revision"]}, {"required": ["local"]}]))]
pub struct Package {
pub git: Option<Loose<String>>,
pub revision: Option<Loose<String>>,
pub local: Option<Loose<String>>,
#[schemars(skip)]
pub package: Option<Loose<String>>,
}
#[derive(JsonSchema)]
#[schemars(inline, extend("additionalProperties" = true))]
#[allow(dead_code)]
struct VersionMap {}
#[derive(JsonSchema)]
#[schemars(inline, extend("x-doc-type" = "list of plugin packages: a name, `name: \"<version>\"`, or a map (see below)"))]
#[allow(dead_code)]
struct Plugins(OneOf<Vec<Item>, OneOf<VersionMap, ()>>);
#[derive(JsonSchema)]
#[schemars(inline)]
#[allow(dead_code)]
struct Item(PluginItem);
pub(super) fn plugins(g: &mut schemars::SchemaGenerator) -> schemars::Schema {
g.subschema_for::<Plugins>()
}