weavatrix-refactor-plan 0.1.0

Evidence metadata, validation profiles, and canonical fingerprints for Weavatrix refactor plans
Documentation
use crate::{PlanError, PlanErrorCode, TextEdit};

pub(super) fn validate_coordinate_overlaps(
    edits: &[TextEdit],
    operation_index: usize,
    path: &str,
) -> Result<(), PlanError> {
    if edits.len() < 2 {
        return Ok(());
    }
    // Well-formed plans list edits in coordinate order; check overlap in one
    // allocation-free pass and only sort when the order is actually mixed.
    let mut ordered = true;
    for pair in edits.windows(2) {
        let left = pair[0].range();
        let right = pair[1].range();
        if (right.start, right.end) < (left.start, left.end) {
            ordered = false;
            break;
        }
        // These two edits are coordinate-ordered, so a start before the
        // previous end is a genuine intersection whatever follows.
        if right.start < left.end {
            return Err(overlap_error(operation_index, path));
        }
    }
    if ordered {
        return Ok(());
    }
    let mut sorted = edits.iter().collect::<Vec<_>>();
    sorted.sort_unstable_by_key(|edit| (edit.range().start, edit.range().end));
    for pair in sorted.windows(2) {
        if pair[1].range().start < pair[0].range().end {
            return Err(overlap_error(operation_index, path));
        }
    }
    Ok(())
}

fn overlap_error(operation_index: usize, path: &str) -> PlanError {
    PlanError::new(PlanErrorCode::OperationConflict, "text edit ranges overlap")
        .at_operation(operation_index)
        .at_path(path)
}