Skip to content

Commit

Permalink
lib/types: Make submoduleWith support unstructured values
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Mar 18, 2020
1 parent af04e52 commit 80a9553
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
6 changes: 6 additions & 0 deletions lib/modules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ rec {
args ? {}
, # This would be remove in the future, Prefer _module.check option instead.
check ? true
, # For unstructured definitions (ones that don't have an
# associated option) this type should be used instead. Needs
# to support attribute values (see attrValueType) if it should
# be combinable with structured options. If null, no
# unstructured definitions are allowed.
unstructuredType ? null
}:
let
# This internal module declare internal options under the `_module'
Expand Down
25 changes: 20 additions & 5 deletions lib/types.nix
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ rec {
{ modules
, specialArgs ? {}
, shorthandOnlyDefinesConfig ? false
, unstructuredType ? null
}@attrs:
let
inherit (lib.modules) evalModules;
Expand All @@ -489,17 +490,18 @@ rec {
in
mkOptionType rec {
name = "submodule";
description = unstructuredType.description or name;
check = x: isAttrs x || isFunction x || path.check x;
merge = loc: defs:
(evalModules {
modules = allModules defs;
inherit specialArgs;
inherit specialArgs unstructuredType;
args.name = last loc;
prefix = loc;
}).config;
emptyValue = { value = {}; };
getSubOptions = prefix: (evalModules
{ inherit modules prefix specialArgs;
{ inherit modules prefix specialArgs unstructuredType;
# This is a work-around due to the fact that some sub-modules,
# such as the one included in an attribute set, expects a "args"
# attribute to be given to the sub-module. As the option
Expand All @@ -524,10 +526,9 @@ rec {
functor = defaultFunctor name // {
type = types.submoduleWith;
payload = {
modules = modules;
specialArgs = specialArgs;
shorthandOnlyDefinesConfig = shorthandOnlyDefinesConfig;
inherit modules specialArgs shorthandOnlyDefinesConfig;
};
wrapped = unstructuredType;
binOp = lhs: rhs: {
modules = lhs.modules ++ rhs.modules;
specialArgs =
Expand All @@ -541,6 +542,20 @@ rec {
else throw "A submoduleWith option is declared multiple times with conflicting shorthandOnlyDefinesConfig values";
};
};
typeMerge = f':
# cannot merge different types
if functor.name != f'.name then null
else
let wrapped = functor.wrapped.typeMerge f'.wrapped.functor;
payload = functor.binOp functor.payload f'.payload;
in functor.type (payload // {
unstructuredType =
if functor.wrapped == null && f'.wrapped == null
then null
else if functor.wrapped != null && f'.wrapped != null && wrapped != null
then wrapped
else throw "A submoduleWith option is declared multiple times with conflicting unstructuredType values";
});
};

# A value from a set of allowed ones.
Expand Down

0 comments on commit 80a9553

Please sign in to comment.