diff --git a/src/rust/inference_trace/src/lib.rs b/src/rust/inference_trace/src/lib.rs index 0ab30748..d4e68042 100644 --- a/src/rust/inference_trace/src/lib.rs +++ b/src/rust/inference_trace/src/lib.rs @@ -37,7 +37,7 @@ pub fn price_for(model: &str) -> Option { /// _trace_dir port: explicit arg wins, else /state. pub fn trace_dir(explicit: Option<&str>, rune_home: &str) -> String { match explicit { - Some(d) => d.trim_end_matches('/').to_string(), + Some(d) => d.trim_end_matches('/').to_owned(), None => format!("{rune_home}/state"), } } @@ -70,19 +70,20 @@ pub fn serialize(trace: &Value) -> String { /// rotate_plan port: the ordered os.replace sequence for one rotation pass /// (I1 general-182: guard tests the SOURCE; loop covers BACKUPS..1 so the /// oldest slot is reachable). Returns [{from, to}] in execution order; the -/// facade performs each replace whose `from` currently exists. +/// facade performs each replace whose `from` currently exists. The newest +/// pair (source = live file) sorts LAST so the facade executes oldest-first. pub fn rotate_plan(name: &str, backups: u32) -> Value { - let pairs: Vec = (1..=backups) - .rev() + let mut pairs: Vec = (1..=backups) .map(|i| { let newer = if i == 1 { - name.to_string() + name.to_owned() } else { format!("{name}.{}", i - 1) }; json!({"from": newer, "to": format!("{name}.{i}")}) }) .collect(); + pairs.reverse(); Value::Array(pairs) } @@ -94,11 +95,13 @@ pub fn should_rotate(current_size: i64, rotate_bytes: i64) -> bool { /// read_select port: json.loads per non-blank line; `limit` trims to the /// last N lines BEFORE parsing (the oracle slices the splitlines list). pub fn read_select(raw: &str, limit: Option) -> Value { - let mut lines: Vec<&str> = raw.lines().collect(); - if let Some(n) = limit { - let start = lines.len().saturating_sub(n); - lines = lines[start..].to_vec(); - } + let lines: Vec<&str> = match limit { + Some(n) => { + let v: Vec<&str> = raw.lines().collect(); + v.into_iter().rev().take(n).collect::>().into_iter().rev().collect() + } + None => raw.lines().collect(), + }; Value::Array( lines .iter() @@ -157,15 +160,9 @@ fn format_value(v: &Value, depth: usize, out: &mut String) { /// cli_tail port: main() body — the full stdout text for tailing `count` /// records (each record pretty-printed + newline) and the 0 exit code. pub fn cli_tail(records: &[Value], count: Option) -> Value { - let trimmed: Vec = match count { - Some(n) => records - .iter() - .rev() - .take(n) - .rev() - .cloned() - .collect(), - None => records.to_vec(), + let trimmed: Vec<&Value> = match count { + Some(n) => records.iter().rev().take(n).collect::>().into_iter().rev().collect(), + None => records.iter().collect(), }; let mut out = String::new(); for r in &trimmed {