use std::path::Path;
use crate::model::Chunk;
use crate::path_lookup::path_lookup_candidates;
pub(crate) fn resolve_chunk<'a>(
chunks: &'a [Chunk],
file_path: &str,
line: usize,
) -> Option<&'a Chunk> {
let lookup_paths = path_lookup_candidates(file_path);
let normalized_input = file_path.replace('\\', "/");
let mut fallback = None;
for chunk in chunks {
let matches_path = lookup_paths.iter().any(|path| path == &chunk.file_path)
|| Path::new(file_path).is_absolute()
&& normalized_input.ends_with(chunk.file_path.as_str());
if matches_path && chunk.start_line <= line && line <= chunk.end_line {
if line < chunk.end_line {
return Some(chunk);
}
if fallback.is_none() {
fallback = Some(chunk);
}
}
}
fallback
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn chunk_lookup_accepts_leading_dot_path() {
let chunks = vec![Chunk::new(
"fn main() {}".to_string(),
"src/main.rs".to_string(),
1,
1,
Some("rust".to_string()),
)];
assert!(resolve_chunk(&chunks, "src/main.rs", 1).is_some());
assert!(resolve_chunk(&chunks, "./src/main.rs", 1).is_some());
}
}