///|
/// A removal proposal whose effective metadata is proven unchanged for every
/// indexed scan. This makes no statement about scans outside the manifest.
pub struct PrunePlan {
priv edit : EditPlan
}
///|
pub fn DatasetIndex::plan_prune(
self : DatasetIndex,
source_path : String,
fields : Array[String],
) -> PrunePlan raise TraceError {
let fields = review_fields(fields)
if fields.is_empty() {
reject(
"empty_prune_fields", source_path, "Name at least one field to remove.",
)
}
guard self.sidecars.search_by(s => s.selector.path == source_path)
is Some(position) else {
reject("unknown_sidecar_path", source_path, "Choose an existing source.")
abort("reject raises")
}
if !self.files
.iter()
.any(file => applies(self.sidecars[position].selector, file)) {
reject(
"unproven_prune", source_path, "No indexed scan uses this source; preservation cannot be demonstrated.",
)
}
let patch = MetadataPatch::from_json(
canonical_json(
Json::object({
"set": Json::object({}),
"remove": Json::array(fields.map(Json::string)),
}),
),
)
let edit = self.plan_edit(source_path, patch)
let check = edit.impact().release_check(EffectiveValues)
if check.decision() != Pass {
reject(
"unsafe_prune",
source_path,
"Removal changes exact effective values or encounters unresolved inheritance; inspect a normal edit plan instead.",
related=check.affected_paths() + check.unresolved_paths(),
)
}
{ edit, }
}
///|
pub fn PrunePlan::after(self : PrunePlan) -> DatasetIndex {
self.edit.after()
}
///|
pub fn PrunePlan::impact(self : PrunePlan) -> ImpactReport {
self.edit.impact()
}
///|
pub fn PrunePlan::patch(self : PrunePlan) -> MetadataPatch {
self.edit.patch
}
///|
pub fn PrunePlan::to_json(self : PrunePlan) -> String {
"{\"edit\":" +
self.edit.to_json() +
",\"guarantee\":\"exact_effective_values_for_all_indexed_scans\"}"
}