use std::sync::LazyLock;
use dashmap::DashMap;
#[derive(Default)]
struct ReadTrackState {
last_key: Option<String>,
consecutive: u32,
}
static TRACKER: LazyLock<DashMap<String, ReadTrackState>> = LazyLock::new(DashMap::new);
pub fn check_and_update(session_id: &str, key: String) -> u32 {
let mut state = TRACKER.entry(session_id.to_string()).or_default();
if state.last_key.as_deref() == Some(&key) {
state.consecutive += 1;
} else {
state.last_key = Some(key);
state.consecutive = 1;
}
state.consecutive
}
pub fn notify_other_tool_call(session_id: &str) {
if let Some(mut state) = TRACKER.get_mut(session_id) {
state.last_key = None;
state.consecutive = 0;
}
}
pub fn read_key(path: &str, line_start: Option<usize>, line_end: Option<usize>) -> String {
format!(
"read:{}:{}:{}",
path,
line_start.unwrap_or(0),
line_end.unwrap_or(0)
)
}
pub fn search_key(
pattern: &str,
path: Option<&str>,
include: Option<&str>,
max_results: usize,
) -> String {
format!(
"search:{}:{}:{}:{}",
pattern,
path.unwrap_or(""),
include.unwrap_or(""),
max_results
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn first_call_returns_one() {
let session = "rt-test-1";
let key = read_key("foo.rs", None, None);
assert_eq!(check_and_update(session, key), 1);
}
#[test]
fn consecutive_same_key_increments() {
let session = "rt-test-2";
let key = || read_key("bar.rs", Some(1), Some(50));
assert_eq!(check_and_update(session, key()), 1);
assert_eq!(check_and_update(session, key()), 2);
assert_eq!(check_and_update(session, key()), 3);
assert_eq!(check_and_update(session, key()), 4);
}
#[test]
fn different_key_resets_count() {
let session = "rt-test-3";
assert_eq!(check_and_update(session, read_key("a.rs", None, None)), 1);
assert_eq!(check_and_update(session, read_key("a.rs", None, None)), 2);
assert_eq!(check_and_update(session, read_key("b.rs", None, None)), 1);
assert_eq!(check_and_update(session, read_key("a.rs", None, None)), 1);
}
#[test]
fn notify_resets_count() {
let session = "rt-test-4";
let key = || read_key("reset.rs", None, None);
check_and_update(session, key());
check_and_update(session, key());
assert_eq!(check_and_update(session, key()), 3);
notify_other_tool_call(session);
assert_eq!(check_and_update(session, key()), 1);
}
}