bulb/src/manifest.rs
2022-12-01 15:25:08 +01:00

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)
}
}