feat: Support better error messages for list/attrs element checks
This commit is contained in:
parent
fe33a82a07
commit
040b719570
1 changed files with 13 additions and 5 deletions
18
yants.nix
18
yants.nix
|
@ -4,17 +4,16 @@
|
||||||
# All types (should) compose as expected.
|
# All types (should) compose as expected.
|
||||||
#
|
#
|
||||||
# TODO:
|
# TODO:
|
||||||
# - error messages for type-checks of map/list elements are bad
|
|
||||||
# - enums?
|
# - enums?
|
||||||
|
|
||||||
{ toPretty ? ((import <nixpkgs> {}).lib.generators.toPretty) }:
|
{ toPretty ? ((import <nixpkgs> {}).lib.generators.toPretty {}) }:
|
||||||
|
|
||||||
# Checks are simply functions of the type `a -> bool` which check
|
# Checks are simply functions of the type `a -> bool` which check
|
||||||
# whether `a` conforms to the specification.
|
# whether `a` conforms to the specification.
|
||||||
with builtins; let
|
with builtins; let
|
||||||
# Internal utilities:
|
# Internal utilities:
|
||||||
typeError = type: val:
|
typeError = type: val:
|
||||||
throw "Expected type '${type}', but value '${toPretty {} val}' is of type '${typeOf val}'";
|
throw "Expected type '${type}', but value '${toPretty val}' is of type '${typeOf val}'";
|
||||||
|
|
||||||
typedef = name: check: {
|
typedef = name: check: {
|
||||||
inherit name check;
|
inherit name check;
|
||||||
|
@ -80,9 +79,18 @@ in (typeSet [
|
||||||
|
|
||||||
# Polymorphic types
|
# Polymorphic types
|
||||||
(poly "option" (t: v: (isNull v) || t.check v))
|
(poly "option" (t: v: (isNull v) || t.check v))
|
||||||
(poly "list" (t: v: isList v && (foldl' (s: e: s && (t.check e)) true v)))
|
|
||||||
|
(poly "list" (t: v: isList v && (foldl' (s: e: s && (
|
||||||
|
if t.check e then true
|
||||||
|
else throw "Expected list element of type '${t.name}', but '${toPretty e}' is of type '${typeOf e}'"
|
||||||
|
)) true v)))
|
||||||
|
|
||||||
(poly "attrs" (t: v:
|
(poly "attrs" (t: v:
|
||||||
isAttrs v && (foldl' (s: e: s && (t.check e)) true (attrValues v))
|
isAttrs v && (foldl' (s: e: s && (
|
||||||
|
if t.check e then true
|
||||||
|
else throw "Expected attribute set element of type '${t.name}', but '${toPretty e}' is of type '${typeOf e}'"
|
||||||
|
)) true (attrValues v))
|
||||||
))
|
))
|
||||||
|
|
||||||
(poly2 "either" (t1: t2: v: t1.check v || t2.check v))
|
(poly2 "either" (t1: t2: v: t1.check v || t2.check v))
|
||||||
]) // { inherit struct; }
|
]) // { inherit struct; }
|
||||||
|
|
Loading…
Add table
Reference in a new issue