pub mod differ;
pub mod patcher;
mod multipatch;
mod patch;
use thiserror::Error;
pub use differ::{DiffAlgorithm, Differ, MyersDiffer, NaiveDiffer};
pub use multipatch::{ApplyResult, MultifilePatch, MultifilePatcher, PatchedFile};
pub use patch::{Chunk, Operation, Patch};
pub use patcher::{NaivePatcher, PatchAlgorithm, Patcher, PatcherAlgorithm};
#[derive(Debug, Error)]
pub enum Error {
#[error("Failed to apply patch: {0}")]
ApplyError(String),
#[error("Invalid patch format: {0}")]
InvalidPatchFormat(String),
#[error("Line {line_num} not found in content while applying patch")]
LineNotFound { line_num: usize },
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("File not found: {path}")]
FileNotFound { path: String },
#[error("Could not parse chunk header: {header}")]
InvalidChunkHeader { header: String },
#[error("Could not parse number '{value}' for {field}: {source}")]
InvalidNumberFormat {
value: String,
field: String,
#[source]
source: std::num::ParseIntError,
},
}
#[cfg(test)]
mod test_utils {
pub(crate) fn load_fixture(name: &str) -> String {
let path = format!("fixtures/code/{}", name);
std::fs::read_to_string(path).unwrap()
}
}
#[cfg(test)]
mod tests {
use crate::{DiffAlgorithm, PatchAlgorithm};
use super::{Differ, Error, patcher::Patcher};
#[test]
fn test_integration_diff_and_patch() -> Result<(), Error> {
let old_content = "line1
line2
line3
line4";
let new_content = "line1
line2 modified
line3
line4";
let differ = Differ::new(old_content, new_content);
let patch = differ.generate();
let patcher = Patcher::new(patch);
let actual_content = patcher.apply(old_content, false)?;
assert_eq!(actual_content, new_content);
Ok(())
}
}