use std::collections::BTreeMap;
use std::fmt::Write;
use super::fetch::FetchPlan;
use super::manifest::{Extension, Lib};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Lockfile {
pub assay: Option<String>,
pub extensions: Vec<LockExtension>,
pub libs: Vec<LockLib>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LockExtension {
pub name: String,
pub version: String,
pub url: String,
pub sha256: BTreeMap<String, String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LockLib {
pub name: String,
pub version: String,
pub url: String,
pub sha256: String,
}
impl LockExtension {
pub fn new(ext: &Extension, plan: &FetchPlan) -> Self {
let sha256 = ext
.sha256
.iter()
.map(|(k, v)| (k.clone(), v.clone()))
.collect();
LockExtension {
name: ext.name.clone(),
version: ext.version.clone(),
url: plan.url.clone(),
sha256,
}
}
}
impl LockLib {
pub fn new(lib: &Lib, plan: &FetchPlan) -> Self {
LockLib {
name: lib.name.clone(),
version: lib.version.clone(),
url: plan.url.clone(),
sha256: lib.sha256.clone(),
}
}
}
impl Lockfile {
pub fn to_lua(&self) -> String {
let mut out = String::with_capacity(256);
out.push_str("-- Generated by `assay install`. Do not edit by hand.\n");
out.push_str("return {\n");
if let Some(v) = &self.assay {
writeln!(out, " assay = {},", lua_string(v)).unwrap();
}
out.push_str(" extensions = {\n");
for e in &self.extensions {
writeln!(out, " {{").unwrap();
writeln!(out, " name = {},", lua_string(&e.name)).unwrap();
writeln!(out, " version = {},", lua_string(&e.version)).unwrap();
writeln!(out, " url = {},", lua_string(&e.url)).unwrap();
out.push_str(" sha256 = {");
let mut first = true;
for (arch, hash) in &e.sha256 {
if !first {
out.push(',');
}
write!(out, " {arch} = {}", lua_string(hash)).unwrap();
first = false;
}
out.push_str(" },\n");
writeln!(out, " }},").unwrap();
}
out.push_str(" },\n");
out.push_str(" libs = {\n");
for l in &self.libs {
writeln!(out, " {{").unwrap();
writeln!(out, " name = {},", lua_string(&l.name)).unwrap();
writeln!(out, " version = {},", lua_string(&l.version)).unwrap();
writeln!(out, " url = {},", lua_string(&l.url)).unwrap();
writeln!(out, " sha256 = {},", lua_string(&l.sha256)).unwrap();
writeln!(out, " }},").unwrap();
}
out.push_str(" },\n");
out.push_str("}\n");
out
}
}
fn lua_string(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 2);
out.push('"');
for c in s.chars() {
match c {
'\\' => out.push_str("\\\\"),
'"' => out.push_str("\\\""),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
c if (c as u32) < 0x20 => write!(out, "\\{}", c as u32).unwrap(),
c => out.push(c),
}
}
out.push('"');
out
}