mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-06-10 03:23:29 +03:00
lib.types: init mergeTypes (#364620)
This commit is contained in:
commit
9d3e649939
2 changed files with 88 additions and 0 deletions
|
@ -2612,4 +2612,45 @@ runTests {
|
||||||
};
|
};
|
||||||
expected = "c";
|
expected = "c";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
testMergeTypesSimple =
|
||||||
|
let
|
||||||
|
mergedType = types.mergeTypes types.str types.str;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
expr = mergedType.name;
|
||||||
|
expected = "str";
|
||||||
|
};
|
||||||
|
|
||||||
|
testMergeTypesFail =
|
||||||
|
let
|
||||||
|
mergedType = types.mergeTypes types.str types.int;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
expr = types.isType "merge-error" mergedType;
|
||||||
|
expected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
testMergeTypesEnum =
|
||||||
|
let
|
||||||
|
enumAB = lib.types.enum ["A" "B"];
|
||||||
|
enumXY = lib.types.enum ["X" "Y"];
|
||||||
|
merged = lib.types.mergeTypes enumAB enumXY; # -> enum [ "A" "B" "X" "Y" ]
|
||||||
|
in
|
||||||
|
{
|
||||||
|
expr = {
|
||||||
|
checkA = merged.check "A";
|
||||||
|
checkB = merged.check "B";
|
||||||
|
checkX = merged.check "X";
|
||||||
|
checkY = merged.check "Y";
|
||||||
|
checkC = merged.check "C";
|
||||||
|
};
|
||||||
|
expected = {
|
||||||
|
checkA = true;
|
||||||
|
checkB = true;
|
||||||
|
checkX = true;
|
||||||
|
checkY = true;
|
||||||
|
checkC = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1125,6 +1125,53 @@ rec {
|
||||||
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
|
addCheck = elemType: check: elemType // { check = x: elemType.check x && check x; };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Merges two option types together.
|
||||||
|
|
||||||
|
:::{.note}
|
||||||
|
Uses the type merge function of the first type, to merge it with the second type.
|
||||||
|
|
||||||
|
Usually types can only be merged if they are of the same type
|
||||||
|
:::
|
||||||
|
|
||||||
|
# Inputs
|
||||||
|
|
||||||
|
: `a` (option type): The first option type.
|
||||||
|
: `b` (option type): The second option type.
|
||||||
|
|
||||||
|
# Returns
|
||||||
|
|
||||||
|
- The merged option type.
|
||||||
|
- `{ _type = "merge-error"; error = "Cannot merge types"; }` if the types can't be merged.
|
||||||
|
|
||||||
|
# Examples
|
||||||
|
:::{.example}
|
||||||
|
## `lib.types.mergeTypes` usage example
|
||||||
|
```nix
|
||||||
|
let
|
||||||
|
enumAB = lib.types.enum ["A" "B"];
|
||||||
|
enumXY = lib.types.enum ["X" "Y"];
|
||||||
|
# This operation could be notated as: [ A ] | [ B ] -> [ A B ]
|
||||||
|
merged = lib.types.mergeTypes enumAB enumXY; # -> enum [ "A" "B" "X" "Y" ]
|
||||||
|
in
|
||||||
|
assert merged.check "A"; # true
|
||||||
|
assert merged.check "B"; # true
|
||||||
|
assert merged.check "X"; # true
|
||||||
|
assert merged.check "Y"; # true
|
||||||
|
merged.check "C" # false
|
||||||
|
```
|
||||||
|
:::
|
||||||
|
*/
|
||||||
|
mergeTypes = a: b:
|
||||||
|
assert isOptionType a && isOptionType b;
|
||||||
|
let
|
||||||
|
merged = a.typeMerge b.functor;
|
||||||
|
in
|
||||||
|
if merged == null then
|
||||||
|
setType "merge-error" { error = "Cannot merge types"; }
|
||||||
|
else
|
||||||
|
merged;
|
||||||
};
|
};
|
||||||
|
|
||||||
in outer_types // outer_types.types
|
in outer_types // outer_types.types
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue