pub(super) const PREVIEW_MAX: usize = 80;
pub(super) fn extract_request_preview(json_bytes: &[u8]) -> Option<String> {
let value: serde_json::Value = serde_json::from_slice(json_bytes).ok()?;
let content = value.get("messages")?.as_array()?.first()?.get("content")?;
Some(payload_headline(content_text(content)?))
}
fn content_text(content: &serde_json::Value) -> Option<&str> {
match content {
serde_json::Value::String(s) => Some(s),
serde_json::Value::Array(blocks) => blocks
.iter()
.find(|b| b.get("type").and_then(|t| t.as_str()) == Some("text"))?
.get("text")?
.as_str(),
_ => None,
}
}
fn payload_headline(goal: &str) -> String {
let payload = crate::start::strip_identity_stamp(goal);
let headline = payload
.lines()
.find(|line| !line.trim().is_empty())
.unwrap_or_default();
truncate_preview(headline)
}
pub(super) fn truncate_preview(s: &str) -> String {
let collapsed: String = s
.chars()
.map(|c| if c.is_whitespace() { ' ' } else { c })
.collect();
let trimmed = collapsed.trim();
if trimmed.chars().count() <= PREVIEW_MAX {
return trimmed.to_string();
}
let head: String = trimmed.chars().take(PREVIEW_MAX - 1).collect();
format!("{head}…")
}