use std::collections::BTreeMap;
use std::fs;
use std::path::{Path, PathBuf};
use anyhow::{Context as ResultExt, Error, Result};
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use crate::config::InlinePlugin;
use crate::context::Context;
#[derive(Debug, Deserialize, Serialize)]
pub struct LockedConfig {
#[serde(flatten)]
pub ctx: Context,
pub plugins: Vec<LockedPlugin>,
pub templates: IndexMap<String, String>,
#[serde(skip)]
pub errors: Vec<Error>,
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum LockedPlugin {
External(LockedExternalPlugin),
Inline(InlinePlugin),
}
#[derive(Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct LockedExternalPlugin {
pub name: String,
pub source_dir: PathBuf,
pub plugin_dir: Option<PathBuf>,
pub files: Vec<PathBuf>,
pub apply: Vec<String>,
pub hooks: BTreeMap<String, String>,
}
impl LockedConfig {
pub fn to_path<P>(&self, path: P) -> Result<()>
where
P: AsRef<Path>,
{
let path = path.as_ref();
if let Some(parent) = path.parent() {
fs::create_dir_all(parent).with_context(|| {
format!("failed to create parent directory `{}`", parent.display())
})?;
}
fs::write(
path,
toml::to_string(&self).context("failed to serialize locked config")?,
)
.with_context(|| format!("failed to write locked config to `{}`", path.display()))?;
Ok(())
}
}