use crate::core::entropy::entropy_compress_to_density;
use crate::core::tokens::count_tokens;
#[must_use]
pub fn to_budget(text: &str, budget_tokens: usize) -> String {
let original = count_tokens(text);
if original == 0 || original <= budget_tokens {
return text.to_string();
}
let minified = minify_if_json(text);
let after_minify = count_tokens(&minified);
if after_minify <= budget_tokens {
return minified;
}
#[allow(clippy::cast_precision_loss)]
let target = (budget_tokens as f64 / after_minify.max(1) as f64).clamp(0.05, 1.0);
let compressed = entropy_compress_to_density(&minified, target).output;
if count_tokens(&compressed) >= original {
text.to_string()
} else {
compressed
}
}
fn minify_if_json(text: &str) -> String {
let trimmed = text.trim();
if !(trimmed.starts_with('{') || trimmed.starts_with('[')) {
return text.to_string();
}
match serde_json::from_str::<serde_json::Value>(trimmed) {
Ok(v) => serde_json::to_string(&v).unwrap_or_else(|_| text.to_string()),
Err(_) => text.to_string(),
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::fmt::Write as _;
#[test]
fn under_budget_is_unchanged() {
let text = "short output";
assert_eq!(to_budget(text, 1000), text);
}
#[test]
fn over_budget_shrinks() {
let big = (0..4000).fold(String::new(), |mut s, i| {
let _ = writeln!(s, "metric {i} = {}", i * 7);
s
});
let out = to_budget(&big, 200);
assert!(count_tokens(&out) < count_tokens(&big));
assert!(!out.is_empty());
}
#[test]
fn is_deterministic() {
let big = (0..3000).fold(String::new(), |mut s, i| {
let _ = writeln!(s, "row {i} payload {}", i % 13);
s
});
let a = to_budget(&big, 150);
let b = to_budget(&big, 150);
assert_eq!(a, b, "compression must be byte-stable across calls (#498)");
}
#[test]
fn json_is_minified_losslessly_first() {
let pretty = "{\n \"a\": 1,\n \"b\": 2,\n \"c\": 3\n}";
let out = to_budget(pretty, 8);
let parsed: serde_json::Value = serde_json::from_str(&out).expect("still valid JSON");
assert_eq!(parsed["a"], 1);
assert_eq!(parsed["c"], 3);
assert!(!out.contains(" "), "insignificant whitespace removed");
}
}