add standard attrs parsing interface
This commit is contained in:
parent
a3afe330c4
commit
3d9e9740d2
2 changed files with 95 additions and 0 deletions
13
nib/parse/default.nix
Normal file
13
nib/parse/default.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
attrs,
|
||||
result,
|
||||
}: let
|
||||
struct = import ./struct.nix {inherit attrs result;};
|
||||
in
|
||||
builtins.listToAttrs [
|
||||
# submodule is included directly to this module (ie self.myFunc)
|
||||
struct
|
||||
|
||||
# submodule content is accessible first by submodule name
|
||||
# then by the name of the content (ie self.submodule.myFunc)
|
||||
]
|
||||
82
nib/parse/struct.nix
Normal file
82
nib/parse/struct.nix
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
attrs,
|
||||
result,
|
||||
}: rec {
|
||||
cmpStructErr' = errBadKeys: errBadValues: path: S: T:
|
||||
if builtins.isAttrs S && builtins.isAttrSet T
|
||||
then let
|
||||
keysS = builtins.attrNames S;
|
||||
keysT = builtins.attrNames T;
|
||||
in
|
||||
# ensure all key names match, then recurse
|
||||
if !(keysS == keysT)
|
||||
then errBadKeys path keysS keysT
|
||||
else
|
||||
(result.firstErr
|
||||
(builtins.map
|
||||
(k: cmpStructErr' errBadKeys errBadValues (path ++ [k]) (keysS.${k}) (keysT.${k}))
|
||||
keysS))
|
||||
else
|
||||
# terminating leaf in recursion tree reached
|
||||
# ensure values' types match
|
||||
(builtins.typeOf S == builtins.typeOf T)
|
||||
|| errBadValues path S T;
|
||||
|
||||
cmpStructErr = errBadKeys: errBadValues: cmpStructErr' errBadKeys errBadValues [];
|
||||
|
||||
cmpStruct =
|
||||
cmpStructErr
|
||||
(path: keysS: keysT:
|
||||
result.Err {
|
||||
reason = "keys";
|
||||
inherit path;
|
||||
})
|
||||
(path: S: T:
|
||||
result.Ok "ok");
|
||||
|
||||
cmpTypedStruct =
|
||||
cmpStructErr
|
||||
(path: keysS: keysT:
|
||||
result.Err {
|
||||
reason = "keys";
|
||||
inherit path;
|
||||
})
|
||||
(path: S: T:
|
||||
result.Err {
|
||||
reason = "values";
|
||||
inherit path;
|
||||
});
|
||||
|
||||
# check is a function taking two structs
|
||||
# and returning a result monad.
|
||||
mergeStruct' = check: template: S: let
|
||||
res = check template S;
|
||||
in
|
||||
result.errOr res ({...}:
|
||||
attrs.mapAttrsRecursive (
|
||||
path: value: let
|
||||
valueS = attrs.attrValueAt S path;
|
||||
in
|
||||
if valueS != null
|
||||
then valueS
|
||||
else value
|
||||
)
|
||||
template);
|
||||
|
||||
mergeStruct = mergeStruct' (S: T: result.Ok "ok");
|
||||
|
||||
mergeTypedStruct = mergeStruct' (
|
||||
cmpStructErr
|
||||
(path: keysS: keysT:
|
||||
result.Ok "ok")
|
||||
(path: S: T:
|
||||
result.Err {
|
||||
reason = "values";
|
||||
inherit path;
|
||||
})
|
||||
);
|
||||
|
||||
mergeStructStrict = mergeStruct' cmpStruct;
|
||||
|
||||
mergeTypedStructStrict = mergeStruct' cmpTypedStruct;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue