feat(tvix/eval): add Value::explain method

This value creates a human-readable explanation of a value. This can
be used to implement documentation related functionality.

For some values, the amount of information displayed can be expanded
quite a bit.

Change-Id: Ie8c400feae909e7680af163596f99060262e4241
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7592
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-12-19 12:58:01 +03:00 committed by tazjin
parent ea7d63e177
commit e306d1d1a1

View file

@ -433,6 +433,39 @@ impl Value {
}
}
}
/// Explain a value in a human-readable way, e.g. by presenting
/// the docstrings of functions if present.
pub fn explain(&self) -> String {
match self {
Value::Null => "the 'null' value".into(),
Value::Bool(b) => format!("the boolean value '{}'", b),
Value::Integer(i) => format!("the integer '{}'", i),
Value::Float(f) => format!("the float '{}'", f),
Value::String(s) => format!("the string '{}'", s),
Value::Path(p) => format!("the path '{}'", p.to_string_lossy()),
Value::Attrs(attrs) => format!("a {}-item attribute set", attrs.len()),
Value::List(list) => format!("a {}-item list", list.len()),
Value::Closure(_f) => format!("a user-defined Nix function"), // TODO: name, loc, etc.
Value::Builtin(b) => {
let mut out = format!("the builtin function '{}'", b.name());
if let Some(docs) = b.documentation() {
out.push_str("\n\n");
out.push_str(docs);
}
out
}
// TODO: handle suspended thunks with a different explanation instead of panicking
Value::Thunk(t) => t.value().explain(),
Value::AttrNotFound
| Value::Blueprint(_)
| Value::DeferredUpvalue(_)
| Value::UnresolvedPath(_) => "an internal Tvix evaluator value".into(),
}
}
}
trait TotalDisplay {