nt/nib/parse/struct.nix

87 lines
2.1 KiB
Nix
Raw Normal View History

{nib, ...}:
2025-12-14 13:21:46 +10:00
with builtins;
with nib.types; rec {
2025-12-13 22:01:54 +10:00
cmpStructErr' = errBadKeys: errBadValues: path: S: T:
2025-12-14 12:59:31 +10:00
if isAttrs S && isAttrs T
2025-12-13 22:01:54 +10:00
then let
2025-12-14 12:59:31 +10:00
keysS = attrNames S;
keysT = attrNames T;
2025-12-13 22:01:54 +10:00
in
# ensure all key names match, then recurse
if !(keysS == keysT)
then errBadKeys path keysS keysT
else
(firstErr
2025-12-14 12:59:31 +10:00
(map
2025-12-13 22:01:54 +10:00
(k: cmpStructErr' errBadKeys errBadValues (path ++ [k]) (keysS.${k}) (keysT.${k}))
keysS))
else
# terminating leaf in recursion tree reached
# ensure values' types match
2025-12-14 12:59:31 +10:00
(typeOf S == typeOf T)
2025-12-13 22:01:54 +10:00
|| errBadValues path S T;
cmpStructErr = errBadKeys: errBadValues: cmpStructErr' errBadKeys errBadValues [];
cmpStruct =
cmpStructErr
(path: _: _:
Err {
2025-12-13 22:01:54 +10:00
reason = "keys";
inherit path;
})
(_: _: _: Ok');
2025-12-13 22:01:54 +10:00
cmpTypedStruct =
cmpStructErr
(path: _: _:
Err {
2025-12-13 22:01:54 +10:00
reason = "keys";
inherit path;
})
(path: _: _:
Err {
2025-12-13 22:01:54 +10:00
reason = "values";
inherit path;
});
cmpTypedPartialStruct =
2025-12-13 22:01:54 +10:00
cmpStructErr
(_: _: _: Ok')
(path: _: _:
Err {
2025-12-13 22:01:54 +10:00
reason = "values";
inherit path;
});
2025-12-13 22:01:54 +10:00
2025-12-14 18:56:07 +10:00
mergeStructs' = f: cond: S: T:
mapAttrsRecursiveCond
cond
(path: valueS: let
valueT = attrValueAt T path;
in
unwrapSome valueT (_: f valueS))
S;
# mergeStruct ensures no properties are evaluated (entirely lazy)
2025-12-14 18:56:07 +10:00
mergeStructs = mergeStruct (x: x);
# given a template struct, and the struct to parse
parseStructFor =
mergeStructs'
(leaf: !isTerminal leaf)
(value:
if isTerminal value
then unwrapTerminal value
else valueS);
# TODO: Define:
# TODO: throwUnreachable = throw "Unreachable code was evaluated..";
# TODO: abortUnreachable = abort "Unreachable code was evaluated...";
mergeStruct = mergeStruct' (_: _: Ok');
2025-12-13 22:01:54 +10:00
# mergeTypedPartialStruct must evaluate properties (not lazy)
# for lazy evaluation use mergeStruct instead!
mergeTypedPartialStruct = mergeStruct' cmpTypedPartialStruct;
2025-12-13 22:01:54 +10:00
}