lib.types: Add unique like uniq, but custom errors

Couldn't extend types.uniq and it had a silly name anyway.
Now we can have better error messages.
This commit is contained in:
Robert Hensing 2022-01-24 01:07:32 +01:00
parent ccb85a53b6
commit ba3e91ed43
3 changed files with 23 additions and 3 deletions

View File

@ -122,8 +122,9 @@ let
mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule mkRenamedOptionModule mkMergedOptionModule mkChangedOptionModule
mkAliasOptionModule mkDerivedConfig doRename; mkAliasOptionModule mkDerivedConfig doRename;
inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions inherit (self.options) isOption mkEnableOption mkSinkUndeclaredOptions
mergeDefaultOption mergeOneOption mergeEqualOption getValues mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
getFiles optionAttrSetToDocList optionAttrSetToDocList' getValues getFiles
optionAttrSetToDocList optionAttrSetToDocList'
scrubOptionValue literalExpression literalExample literalDocBook scrubOptionValue literalExpression literalExample literalDocBook
showOption showFiles unknownModule mkOption; showOption showFiles unknownModule mkOption;
inherit (self.types) isType setType defaultTypeMerge defaultFunctor inherit (self.types) isType setType defaultTypeMerge defaultFunctor

View File

@ -134,6 +134,12 @@ rec {
throw "The unique option `${showOption loc}' is defined multiple times. Definition values:${showDefs defs}" throw "The unique option `${showOption loc}' is defined multiple times. Definition values:${showDefs defs}"
else (head defs).value; else (head defs).value;
mergeUniqueOption = { message }: loc: defs:
if length defs == 1
then (head defs).value
else assert length defs > 1;
throw "The option `${showOption loc}' is defined multiple times.\n${message}\nDefinition values:${showDefs defs}";
/* "Merge" option definitions by checking that they all have the same value. */ /* "Merge" option definitions by checking that they all have the same value. */
mergeEqualOption = loc: defs: mergeEqualOption = loc: defs:
if defs == [] then abort "This case should never happen." if defs == [] then abort "This case should never happen."

View File

@ -32,7 +32,6 @@ let
last last
length length
tail tail
unique
; ;
inherit (lib.attrsets) inherit (lib.attrsets)
attrNames attrNames
@ -48,6 +47,7 @@ let
mergeDefaultOption mergeDefaultOption
mergeEqualOption mergeEqualOption
mergeOneOption mergeOneOption
mergeUniqueOption
showFiles showFiles
showOption showOption
; ;
@ -470,6 +470,18 @@ rec {
nestedTypes.elemType = elemType; nestedTypes.elemType = elemType;
}; };
unique = { message }: type: mkOptionType rec {
name = "unique";
inherit (type) description check;
merge = mergeUniqueOption { inherit message; };
emptyValue = type.emptyValue;
getSubOptions = type.getSubOptions;
getSubModules = type.getSubModules;
substSubModules = m: uniq (type.substSubModules m);
functor = (defaultFunctor name) // { wrapped = type; };
nestedTypes.elemType = type;
};
# Null or value of ... # Null or value of ...
nullOr = elemType: mkOptionType rec { nullOr = elemType: mkOptionType rec {
name = "nullOr"; name = "nullOr";
@ -599,6 +611,7 @@ rec {
# A value from a set of allowed ones. # A value from a set of allowed ones.
enum = values: enum = values:
let let
inherit (lib.lists) unique;
show = v: show = v:
if builtins.isString v then ''"${v}"'' if builtins.isString v then ''"${v}"''
else if builtins.isInt v then builtins.toString v else if builtins.isInt v then builtins.toString v