use super::convert::val_to_jq_capped;
use super::format::{Indent, render};
use super::jaq_json::Val;
use std::cell::RefCell;
pub(super) const MAX_MESSAGE_BYTES: usize = 1 << 20;
thread_local! {
static BUF: RefCell<String> = const { RefCell::new(String::new()) };
}
fn push(s: &str) {
BUF.with(|b| {
let mut b = b.borrow_mut();
let room = MAX_MESSAGE_BYTES.saturating_sub(b.len());
if s.len() <= room {
b.push_str(s);
} else {
let mut end = room;
while !s.is_char_boundary(end) {
end -= 1;
}
b.push_str(&s[..end]);
}
});
}
fn compact(v: &Val) -> String {
match val_to_jq_capped(v, MAX_MESSAGE_BYTES) {
Some(j) => render(&j, Indent::Compact),
None => "<value too large>".to_string(),
}
}
pub(super) fn stderr(v: &Val) {
match v {
Val::TStr(s) | Val::BStr(s) => {
let bytes: &[u8] = (**s).as_ref();
push(&String::from_utf8_lossy(bytes));
}
_ => push(&compact(v)),
}
}
pub(super) fn debug(v: &Val) {
push(&format!("[\"DEBUG:\",{}]\n", compact(v)));
}
pub(super) fn take() -> String {
BUF.with(|b| std::mem::take(&mut *b.borrow_mut()))
}