use mumu::parser::types::Value;
pub fn escape_str(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 8);
for ch in s.chars() {
match ch {
'\\' => out.push_str("\\\\"),
'"' => out.push_str("\\\""),
'\n' => out.push_str("\\n"),
'\r' => out.push_str("\\r"),
'\t' => out.push_str("\\t"),
other => out.push(other),
}
}
out
}
pub fn short_type(v: &Value) -> &'static str {
match v {
Value::Bool(_) => "bool",
Value::Int(_) => "int",
Value::Long(_) => "long",
Value::Float(_) => "float",
Value::SingleString(_) => "string",
Value::IntArray(_) => "int_array",
Value::FloatArray(_) => "float_array",
Value::BoolArray(_) => "bool_array",
Value::StrArray(_) => "str_array",
Value::Int2DArray(_) => "int2d_array",
Value::Float2DArray(_) => "float2d_array",
Value::MixedArray(_) => "mixed_array",
Value::KeyedArray(_) => "keyed_array",
Value::KeyedError(_) => "keyed_error",
Value::Function(_) => "function",
Value::Stream(_) => "stream",
Value::Iterator(_) => "iterator",
Value::Tensor(_) => "tensor",
Value::Ref(_) => "ref",
Value::Regex(_) => "regex",
Value::Undefined => "undefined",
Value::Placeholder => "placeholder",
}
}
pub fn leaf_preview(v: &Value, quote: bool, show_types: bool) -> String {
let body = match v {
Value::SingleString(s) if quote => format!("\"{}\"", escape_str(s)),
Value::SingleString(s) => s.clone(),
Value::Int(i) => i.to_string(),
Value::Long(l) => l.to_string(),
Value::Float(f) => f.to_string(),
Value::Bool(b) => b.to_string(),
Value::Regex(rx) => format!("Regex(/{}{}/)", rx.pattern, rx.flags),
Value::Function(_) => "[Function]".to_string(),
Value::Stream(h) => format!("<Stream id={}, label={}>", h.stream_id, h.label),
Value::Iterator(_) => "[Iterator]".to_string(),
Value::Tensor(_) => "[Tensor]".to_string(),
Value::Undefined => "undefined".to_string(),
Value::Placeholder => "_".to_string(),
Value::KeyedError(m) => {
let msg = m.get("message").and_then(|v| if let Value::SingleString(s)=v {Some(s)} else {None}).cloned();
match msg {
Some(s) => format!("Error(\"{}\")", escape_str(&s)),
None => "Error".to_string(),
}
}
Value::KeyedArray(_) => "{…}".to_string(),
Value::MixedArray(_) => "[…]".to_string(),
Value::IntArray(xs) => format!("[int; {}]", xs.len()),
Value::FloatArray(xs) => format!("[float; {}]", xs.len()),
Value::BoolArray(xs) => format!("[bool; {}]", xs.len()),
Value::StrArray(xs) => format!("[str; {}]", xs.len()),
Value::Int2DArray(rows) => {
let cols = rows.get(0).map(|r| r.len()).unwrap_or(0);
format!("[int; {}x{}]", rows.len(), cols)
}
Value::Float2DArray(rows) => {
let cols = rows.get(0).map(|r| r.len()).unwrap_or(0);
format!("[float; {}x{}]", rows.len(), cols)
}
Value::Ref(_) => "↻".to_string(),
};
if show_types {
format!("{} ({})", body, short_type(v))
} else {
body
}
}