use anyhow::Result;
use indexmap::IndexMap;
use serde::Deserialize;
use std::{fmt::Debug, fs::File, io::BufReader, path::Path};
#[derive(Debug, Deserialize)]
pub(crate) struct Plan {
pub(crate) source: String,
pub(crate) targets: IndexMap<String, TargetMapping>,
}
impl Plan {
pub(crate) fn from_path(path: &Path) -> Result<Self> {
let file = File::open(path)?;
let reader = BufReader::new(file);
let plan = serde_json::from_reader(reader)?;
Ok(plan)
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub(crate) enum TargetMapping {
Identity(Vec<String>),
Mapped(IndexMap<String, Mapped>),
}
impl TargetMapping {
pub(crate) fn iter(&self) -> Vec<(&str, &str)> {
match self {
TargetMapping::Identity(inputs) => {
inputs.iter().map(|i| (i.as_str(), i.as_str())).collect()
}
TargetMapping::Mapped(mapping) => mapping
.iter()
.map(|(source_input, mapped)| {
(
source_input.as_str(),
match mapped {
Mapped::Named(target_input) => target_input.as_str(),
Mapped::Same(true) => source_input.as_str(),
_ => panic!("invalid mapped value"),
},
)
})
.collect(),
}
}
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub(crate) enum Mapped {
Named(String),
Same(bool),
}