90 lines
2.3 KiB
Rust
90 lines
2.3 KiB
Rust
|
#![allow(dead_code)]
|
||
|
|
||
|
use semver::VersionReq;
|
||
|
|
||
|
use crate::errors::JsonError;
|
||
|
use url::Url;
|
||
|
use serde::Deserialize;
|
||
|
use std::{
|
||
|
collections::HashMap,
|
||
|
path::{
|
||
|
PathBuf,
|
||
|
Path
|
||
|
},
|
||
|
fs
|
||
|
};
|
||
|
use mlua::prelude::{
|
||
|
LuaResult,
|
||
|
LuaError
|
||
|
};
|
||
|
|
||
|
|
||
|
#[derive(Deserialize, Debug)]
|
||
|
pub struct Manifest {
|
||
|
#[serde(skip, default = "default_url")]
|
||
|
pub url: Url,
|
||
|
pub plugins: Vec<Plugin>,
|
||
|
pub repos: Option<Vec<String>>
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, Debug)]
|
||
|
pub struct PluginReference {
|
||
|
pub optional: Option<bool>,
|
||
|
pub version: Option<VersionReq>
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, Debug)]
|
||
|
struct File {
|
||
|
pub url: Url,
|
||
|
pub checksum: String,
|
||
|
pub arch: String,
|
||
|
pub path: PathBuf
|
||
|
}
|
||
|
|
||
|
#[derive(Deserialize, Debug)]
|
||
|
pub struct Plugin {
|
||
|
pub name: String,
|
||
|
pub description: String,
|
||
|
pub version: VersionReq,
|
||
|
pub mod_version: Option<String>,
|
||
|
pub provides: Option<Vec<String>>,
|
||
|
pub dependencies: Option<HashMap<String, PluginReference>>,
|
||
|
pub conflicts: Option<HashMap<String, PluginReference>>,
|
||
|
pub path: Option<PathBuf>,
|
||
|
pub remote: Option<String>,
|
||
|
pub url: Option<Url>,
|
||
|
pub checksum: Option<String>,
|
||
|
}
|
||
|
|
||
|
fn default_url() -> Url {
|
||
|
Url::parse("https://example.com").unwrap()
|
||
|
}
|
||
|
|
||
|
impl Manifest {
|
||
|
pub fn parse<P>(path: P, url: Url) -> LuaResult<Manifest>
|
||
|
where
|
||
|
P: AsRef<Path>
|
||
|
{
|
||
|
let data = fs::read(path)?;
|
||
|
|
||
|
let mut manifest: Manifest = serde_json::from_slice(data.as_slice()).map_err(JsonError)?;
|
||
|
|
||
|
(&mut manifest).url = url;
|
||
|
|
||
|
// Make sure that a plugin doesn't contain both 'url'/'checksum' and 'remote'
|
||
|
for p in manifest.plugins.iter() {
|
||
|
if p.url.is_some() && p.checksum.is_none() {
|
||
|
return Err(LuaError::external(format!("Could not parse manifest from {}!\nField 'url' depends on field 'checksum'", manifest.url)));
|
||
|
} else if p.url.is_none() && p.checksum.is_some() {
|
||
|
return Err(LuaError::external(format!("Could not parse manifest from {}!\nField 'checksum' depends on field 'url'", manifest.url)));
|
||
|
};
|
||
|
|
||
|
if p.remote.is_some() && p.url.is_some() {
|
||
|
return Err(LuaError::external(format!("Could not parse manifest from {}!\nConflicting fields 'remote' and 'url'", manifest.url)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Ok(manifest)
|
||
|
}
|
||
|
}
|