lib.types.attrTag: Support type merging
This commit is contained in:
parent
42d3b54f0d
commit
0bc9783221
|
@ -39,6 +39,9 @@ in
|
||||||
yay = mkOption {
|
yay = mkOption {
|
||||||
type = types.int;
|
type = types.int;
|
||||||
};
|
};
|
||||||
|
extensible = mkOption {
|
||||||
|
type = types.enum [ "foo" ];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -71,6 +74,9 @@ in
|
||||||
nay = mkOption {
|
nay = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
};
|
};
|
||||||
|
extensible = mkOption {
|
||||||
|
type = types.enum [ "bar" ];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -89,11 +95,15 @@ in
|
||||||
nested.right.left = "not a number";
|
nested.right.left = "not a number";
|
||||||
merged.negative.nay = false;
|
merged.negative.nay = false;
|
||||||
merged.positive.yay = 100;
|
merged.positive.yay = 100;
|
||||||
|
merged.extensi-foo.extensible = "foo";
|
||||||
|
merged.extensi-bar.extensible = "bar";
|
||||||
okChecks =
|
okChecks =
|
||||||
assert config.intStrings.hello.right == "hello world";
|
assert config.intStrings.hello.right == "hello world";
|
||||||
assert config.intStrings.numberOne.left == 1;
|
assert config.intStrings.numberOne.left == 1;
|
||||||
assert config.merged.negative.nay == false;
|
assert config.merged.negative.nay == false;
|
||||||
assert config.merged.positive.yay == 100;
|
assert config.merged.positive.yay == 100;
|
||||||
|
assert config.merged.extensi-foo.extensible == "foo";
|
||||||
|
assert config.merged.extensi-bar.extensible == "bar";
|
||||||
# assert lib.foldl' (a: b: builtins.trace b a) true (lib.attrNames config.docs);
|
# assert lib.foldl' (a: b: builtins.trace b a) true (lib.attrNames config.docs);
|
||||||
assert config.docs."submodules.<name>.foo.bar".type == "signed integer";
|
assert config.docs."submodules.<name>.foo.bar".type == "signed integer";
|
||||||
assert config.docs."submodules.<name>.qux".type == "string";
|
assert config.docs."submodules.<name>.qux".type == "string";
|
||||||
|
|
|
@ -667,7 +667,28 @@ rec {
|
||||||
}
|
}
|
||||||
else throw "The option `${showOption loc}` is defined as ${lib.strings.escapeNixIdentifier choice}, but ${lib.strings.escapeNixIdentifier choice} is not among the valid choices (${choicesStr}). Value ${choice} was defined in ${showFiles (getFiles defs)}.";
|
else throw "The option `${showOption loc}` is defined as ${lib.strings.escapeNixIdentifier choice}, but ${lib.strings.escapeNixIdentifier choice} is not among the valid choices (${choicesStr}). Value ${choice} was defined in ${showFiles (getFiles defs)}.";
|
||||||
nestedTypes = tags;
|
nestedTypes = tags;
|
||||||
functor = (defaultFunctor "attrTagWith") // { payload = { inherit tags; }; binOp = a: b: { tags = a.tags // b.tags; }; };
|
functor = (defaultFunctor "attrTagWith") // {
|
||||||
|
payload = { inherit tags; };
|
||||||
|
binOp =
|
||||||
|
let
|
||||||
|
# Add metadata in the format that submodules work with
|
||||||
|
wrapOptionDecl =
|
||||||
|
option: { options = option; _file = "<attrTag {...}>"; pos = null; };
|
||||||
|
in
|
||||||
|
a: b: {
|
||||||
|
tags = a.tags // b.tags //
|
||||||
|
mapAttrs
|
||||||
|
(tagName: bOpt:
|
||||||
|
lib.mergeOptionDecls
|
||||||
|
# FIXME: loc is not accurate; should include prefix
|
||||||
|
# Fortunately, it's only used for error messages, where a "relative" location is kinda ok.
|
||||||
|
# It is also returned though, but use of the attribute seems rare?
|
||||||
|
[tagName]
|
||||||
|
[ (wrapOptionDecl a.tags.${tagName}) (wrapOptionDecl bOpt) ]
|
||||||
|
)
|
||||||
|
(builtins.intersectAttrs a.tags b.tags);
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
uniq = unique { message = ""; };
|
uniq = unique { message = ""; };
|
||||||
|
|
Loading…
Reference in New Issue
Block a user