diff options
author | Vincent Ambo <mail@tazj.in> | 2022-12-19T09·58+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-12-22T19·09+0000 |
commit | e306d1d1a1cf5068277b774f586fc22e05dd671f (patch) | |
tree | 512e70edc6e706c913d77b7f2f461eed4e796fc1 | |
parent | ea7d63e177d8a951e30bc00918081eb069e2efb2 (diff) |
feat(tvix/eval): add Value::explain method r/5475
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
-rw-r--r-- | tvix/eval/src/value/mod.rs | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index 3e59c19c3196..711ffcc6f78f 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -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 { |