use crate::config::WikiConfig;
use crate::error::WikiError;
use crate::splice;
use crate::wiki::Wiki;
pub fn rename(
wiki: &mut Wiki,
old_name: &str,
new_name: &str,
dirs: &Option<Vec<String>>,
write: bool,
) -> Result<usize, WikiError> {
let mut changes: super::FileEdits = Vec::new();
for file_path in wiki.all_scannable_files() {
let rel_path = wiki.rel_path(&file_path);
if let Some(dir_filter) = dirs
&& !WikiConfig::matches_dirs(rel_path, dir_filter)
{
continue;
}
let source = wiki.source(&file_path)?;
let mut file_edits = Vec::new();
let headings = wiki.headings(&file_path)?;
for h in headings {
if h.text.eq_ignore_ascii_case(old_name) {
let heading_src = &source[h.byte_range.clone()];
if let Some(text_offset) = heading_src.find(&h.text) {
let abs_start = h.byte_range.start + text_offset;
let abs_end = abs_start + h.text.len();
file_edits.push((abs_start..abs_end, new_name.to_owned()));
}
}
}
let wikilinks = wiki.wikilinks(&file_path)?;
for wl in wikilinks {
if let Some(crate::page::WikilinkFragment::Heading(ref heading)) = wl.fragment
&& heading.as_str().eq_ignore_ascii_case(old_name)
{
let wl_src = &source[wl.byte_range.clone()];
let new_wl = wl_src.replace(heading.as_str(), new_name);
if new_wl != wl_src {
file_edits.push((wl.byte_range.clone(), new_wl));
}
}
}
if !file_edits.is_empty() {
changes.push((file_path, source.to_owned(), file_edits));
}
}
let mut total_changes = 0;
for (file_path, source, file_edits) in changes {
let rel_path = wiki.rel_path(&file_path);
if write {
let result = splice::apply(&source, &file_edits);
wiki.write_file(&file_path, &result)?;
println!(
"{}: renamed {} occurrence(s)",
rel_path.display(),
file_edits.len()
);
} else {
print!("{}", splice::diff(&source, rel_path, &file_edits));
}
total_changes += file_edits.len();
}
Ok(total_changes)
}