feat(tvix/eval): add CoercionKind::ThunksOnly
Signed-off-by: Adam Joseph <adam@westernsemico.com> Change-Id: I92acb7e6099a4796d953b2d4d02cca4076ed0fb1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/7426 Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
This commit is contained in:
parent
bab6ae136f
commit
7606e62a2f
2 changed files with 12 additions and 4 deletions
|
@ -293,6 +293,7 @@ to a missing value in the attribute set(s) included via `with`."#,
|
|||
|
||||
ErrorKind::NotCoercibleToString { kind, from } => {
|
||||
let kindly = match kind {
|
||||
CoercionKind::ThunksOnly => "thunksonly",
|
||||
CoercionKind::Strong => "strongly",
|
||||
CoercionKind::Weak => "weakly",
|
||||
};
|
||||
|
|
|
@ -107,8 +107,10 @@ macro_rules! gen_is {
|
|||
}
|
||||
|
||||
/// Describes what input types are allowed when coercing a `Value` to a string
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, Debug)]
|
||||
pub enum CoercionKind {
|
||||
/// Force thunks, but perform no other coercions.
|
||||
ThunksOnly,
|
||||
/// Only coerce already "stringly" types like strings and paths, but also
|
||||
/// coerce sets that have a `__toString` attribute. Equivalent to
|
||||
/// `!coerceMore` in C++ Nix.
|
||||
|
@ -176,18 +178,21 @@ impl Value {
|
|||
|
||||
// coercions that are always done
|
||||
(Value::String(s), _) => Ok(s.clone()),
|
||||
|
||||
// TODO(sterni): Think about proper encoding handling here. This needs
|
||||
// general consideration anyways, since one current discrepancy between
|
||||
// C++ Nix and Tvix is that the former's strings are arbitrary byte
|
||||
// sequences without NUL bytes, whereas Tvix only allows valid
|
||||
// Unicode. See also b/189.
|
||||
(Value::Path(p), _) => Ok(p.to_string_lossy().into_owned().into()),
|
||||
(Value::Path(p), kind) if kind != CoercionKind::ThunksOnly => {
|
||||
Ok(p.to_string_lossy().into_owned().into())
|
||||
}
|
||||
|
||||
// Attribute sets can be converted to strings if they either have an
|
||||
// `__toString` attribute which holds a function that receives the
|
||||
// set itself or an `outPath` attribute which should be a string.
|
||||
// `__toString` is preferred.
|
||||
(Value::Attrs(attrs), _) => {
|
||||
(Value::Attrs(attrs), kind) if kind != CoercionKind::ThunksOnly => {
|
||||
match (attrs.select("__toString"), attrs.select("outPath")) {
|
||||
(None, None) => Err(ErrorKind::NotCoercibleToString { from: "set", kind }),
|
||||
|
||||
|
@ -250,7 +255,9 @@ impl Value {
|
|||
.unwrap_or_else(|| Ok("".into()))
|
||||
}
|
||||
|
||||
(Value::Closure(_), _)
|
||||
(Value::Path(_), _)
|
||||
| (Value::Attrs(_), _)
|
||||
| (Value::Closure(_), _)
|
||||
| (Value::Builtin(_), _)
|
||||
| (Value::Null, _)
|
||||
| (Value::Bool(_), _)
|
||||
|
|
Loading…
Reference in a new issue