use std::collections::HashSet;
use std::fs;
use std::path::Path;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct NeighborEntry {
pub file_path: String,
pub line_start: u32,
pub line_end: u32,
pub name: Option<String>,
pub score: f32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct ChangeNeighborsMarker {
pub edited_path: String,
pub neighbors: Vec<NeighborEntry>,
}
pub(crate) fn write(marker_path: &Path, marker: &ChangeNeighborsMarker) {
if let Ok(json) = serde_json::to_string(marker) {
let _ = fs::write(marker_path, json);
}
}
pub(crate) fn read(marker_path: &Path) -> Option<ChangeNeighborsMarker> {
let content = fs::read_to_string(marker_path).ok()?;
serde_json::from_str(&content).ok()
}
pub(crate) fn read_and_remove(marker_path: &Path) -> Option<ChangeNeighborsMarker> {
let marker = read(marker_path)?;
let _ = fs::remove_file(marker_path);
Some(marker)
}
pub(crate) fn seen_key(
edited_path: &str,
neighbor_file: &str,
neighbor_name: Option<&str>,
) -> String {
format!(
"{edited_path}\t{neighbor_file}\t{}",
neighbor_name.unwrap_or("")
)
}
pub(crate) fn read_seen(seen_path: &Path) -> HashSet<String> {
fs::read_to_string(seen_path)
.map(|content| content.lines().map(str::to_owned).collect())
.unwrap_or_default()
}
pub(crate) fn append_seen(seen_path: &Path, keys: &[String]) {
if keys.is_empty() {
return;
}
use std::io::Write;
if let Ok(mut file) = fs::OpenOptions::new()
.create(true)
.append(true)
.open(seen_path)
{
for key in keys {
let _ = writeln!(file, "{key}");
}
}
}