pub(super) fn resolve_line_window(
start_line: Option<i64>,
offset: Option<i64>,
limit: Option<i64>,
) -> Option<(i64, Option<i64>)> {
let start = start_line.or(offset).map(|v| v.max(1));
let limit = limit.filter(|&l| l > 0);
match (start, limit) {
(Some(s), l) => Some((s, l)),
(None, Some(_)) => Some((1, limit)),
(None, None) => None,
}
}
pub(super) fn lines_mode(start: i64, limit: Option<i64>) -> String {
match limit {
Some(l) => format!("lines:{start}-{}", start + l - 1),
None => format!("lines:{start}-999999"),
}
}
pub(super) fn anchored_lines_mode(start: i64, limit: Option<i64>) -> String {
match limit {
Some(l) => format!("anchored:{start}-{}", start + l - 1),
None => format!("anchored:{start}-999999"),
}
}
pub(super) fn resolve_instruction_file_mode(path: &str, mode: &str) -> (String, Option<String>) {
if !crate::tools::ctx_read::is_instruction_file(path)
|| matches!(mode, "full" | "raw" | "anchored")
|| mode.starts_with("anchored:")
|| mode.starts_with("lines:")
{
return (mode.to_string(), None);
}
(
"full".to_string(),
Some(format!(
"[mode overridden: {mode} -> full, reason=instruction file requires complete content]"
)),
)
}
pub(super) fn scoped_read_ranges(
mode: &str,
) -> Option<Vec<crate::tools::ctx_read::mode::LineRange>> {
use crate::tools::ctx_read::{ReadMode, mode::LineRange};
match mode.parse::<ReadMode>().ok()? {
ReadMode::Lines(range) | ReadMode::Anchored(Some(range)) => Some(vec![range]),
ReadMode::LinesMulti(payload) => Some(
payload
.split(',')
.filter_map(|part| {
let (start, end) = part.split_once('-').unwrap_or((part, part));
Some(LineRange::new(start.parse().ok()?, end.parse().ok()?))
})
.collect(),
),
_ => None,
}
}
pub(super) fn hint_intersects_ranges(
hint: &crate::core::cross_source_hints::CrossSourceHint,
ranges: &[crate::tools::ctx_read::mode::LineRange],
graph: &crate::core::property_graph::CodeGraph,
relative_path: &str,
) -> bool {
if hint.relation != "health_hotspot" {
return false;
}
let Some((_, symbol)) = hint.source_uri.rsplit_once('#') else {
return false;
};
let Ok(Some(node)) = graph.get_node_by_symbol(symbol, relative_path) else {
return false;
};
let (Some(start), Some(end)) = (node.line_start, node.line_end) else {
return false;
};
ranges
.iter()
.any(|range| start <= range.end as usize && end >= range.start as usize)
}
pub(super) fn apply_line_window(
mode: &mut String,
fresh: &mut bool,
explicit_mode: bool,
start_line: Option<i64>,
offset: Option<i64>,
limit: Option<i64>,
) {
let preserve_explicit_window = explicit_mode
&& start_line.is_none()
&& offset.is_none()
&& limit.is_some_and(|value| value > 0)
&& matches!(
mode.parse::<crate::tools::ctx_read::ReadMode>(),
Ok(crate::tools::ctx_read::ReadMode::Lines(_)
| crate::tools::ctx_read::ReadMode::Anchored(Some(_)))
);
if preserve_explicit_window {
return;
}
let Some((start, limit)) = resolve_line_window(start_line, offset, limit) else {
return;
};
if start <= 1 && limit.is_none() {
return;
}
*fresh = true;
if mode == "anchored" {
*mode = anchored_lines_mode(start, limit);
} else {
*mode = lines_mode(start, limit);
}
}
pub(super) fn resolve_raw_alias(arg_raw: bool, mode_arg: Option<String>) -> Option<String> {
if arg_raw {
Some("raw".to_string())
} else {
mode_arg
}
}