nixfiles/libs/core/lib/set/default.nix
Sebastian Walz 860d31cee1
Tohu vaBohu
2023-04-21 00:22:52 +02:00

426 lines
9.8 KiB
Nix

{ debug, intrinsics, list, type, ... }:
let
all
= predicate:
dictionary:
(partition predicate dictionary).wrong == {};
all'
= predicate:
dictionary:
(partition' predicate dictionary).wrong == {};
any
= predicate:
dictionary:
(partition predicate dictionary).right != {};
any'
= predicate:
dictionary:
(partition' predicate dictionary).right != {};
callValues
= argument:
mapValues (value: value argument);
# string -> [ { T... } ] -> [ T ]
# where T: Any
collect
= intrinsics.catAttrs;
filter# F -> { T } -> { T }
# where
# F: string -> T -> bool,
# T: Any
= predicate:
{ ... } @ self:
(partition predicate self).right;
# { T } -> [ string ] -> { T... }
# where T: Any:
filterByName
= { ... } @ self:
keys:
fromList
(
list.map
(
name:
{
inherit name;
value = self.${name};
}
)
keys
);
filterKeys# F -> { T } -> { T }
# where
# F: string -> bool,
# T: Any
= predicate:
{ ... } @ self:
(partitionByName predicate self).right;
filterValue# F -> { T } -> { T }
# where
# F: T -> bool,
# T: Any
= predicate:
{ ... } @ self:
(partitionByValue predicate self).right;
# F -> S -> { T... } -> S
# where
# F: S -> string -> T -> S,
# T, S: Any:
fold
= next:
state:
{ ... } @ self:
list.fold
(
state:
name:
next state name self.${name}
)
state
( names self );
# F -> S -> { T... } -> S
# where
# F: S -> { name: string; value: T; } -> S,
# T, S: Any:
fold'
= next:
fold
(
state:
name:
value:
next
state
{ inherit name value; }
);
# F -> S -> { T... } -> S
# where
# F: S -> string -> T -> S,
# T, S: Any:
foldValues
= next:
state:
{ ... } @ self:
list.fold
(
state:
name:
next state self.${name}
)
state
( names self );
# [ { name: string, value: T } ] -> { string -> T }
# where T: Any:
fromList
= intrinsics.listToAttrs;
# D -> [ string ] -> { string -> D }
fromListDefault
= value:
listOfKeys:
fromList
(
list.map
(name: { inherit name value; })
listOfKeys
);
# F -> [ T ] -> { R... }
# where
# F: int -> T -> { name: string, value: R },
# T, R: Any:
fromListIMapped
= convert:
input:
fromList (list.imap convert input);
# F -> [ T ] -> { R... }
# where
# F: int -> T -> R,
# T, R: Any:
fromListIMappedValue
= convert:
input:
fromList
(
list.imap
(
index:
name:
{
inherit name;
value = convert index name;
}
)
input
);
# F -> [ T ] -> { R... }
# where
# F: T -> { name: string, value: R },
# T, R: Any:
fromListMapped
= convert:
keyValuePairs:
fromList (list.map convert keyValuePairs);
# F -> [ T ] -> { R... }
# where
# F: T -> R,
# T, R: Any:
fromListMappedValue
= convert:
input:
fromList
(
list.map
(
name:
{
inherit name;
value = convert name;
}
)
input
);
generate
= generator:
count:
fromList (list.generate generator count);
# string -> { T... } -> T
# where T: Any:
get
= intrinsics.getAttr
or (
name:
self:
self.${name}
);
getKeySource#: string -> { string -> T } -> { column: int; file: string; line: int; }
= intrinsics.unsafeGetAttrPos;
# string -> { T... } -> D -> T | D
# where T, D: Any:
getOr
= name:
self:
default:
self.${name} or default;
getSource
= { ... } @ self:
if self != {}
then
getKeySource (list.head (names self)) self
else
null;
# string -> { ... } -> bool
hasAttribute
= intrinsics.hasAttr
or (
name:
self:
self.${name} or true == self.${name} or false
);
ifOrEmpty
= condition:
value:
if condition
then
value
else
{};
# { string -> T } -> { string -> U } -> { string -> U }
intersect
= intrinsics.intersectAttrs;
isInstanceOf = intrinsics.isAttrs;
map = intrinsics.mapAttrs;
mapFold
= convert:
operator:
fold
(
state:
name:
value:
operator state (convert name value)
);
mapFold'
= convert:
operator:
fold'
(
state:
entry:
operator state (convert entry)
);
mapNamesAndValues#: F -> { T... } -> { R... }
# where
# F: string -> T -> { name: string, value: R }
# T, R: Any,
= convert:
self:
fromList (mapToList convert self);
# F -> { T... } -> [ R ]
# where
# F: string -> T -> R,
# T, R: Any:
mapToList
= convert:
{ ... } @ self:
values (map convert self);
# F -> { T... } -> [ R ]
# where
# F: string -> T -> R,
# T, R: Any:
mapToListConcatted
= convert:
{ ... } @ self:
list.concat (values (map convert self));
# F -> { T... } -> { R... }
# where
# F: T -> R,
# T, R: Any:
mapValues
= convert:
map (_: convert);
name
= map
(
name:
value:
value // { inherit name; }
);
names = intrinsics.attrNames;
orNull
= value:
isInstanceOf value || value == null;
pair#: n, T @ n:[ string ] -> n:[ T ] -> { T }
= listOfNames:
listOfValues:
if list.isInstanceOf listOfNames
&& list.isInstanceOf listOfValues
&& list.length listOfNames == list.length listOfValues
then
fromListIMappedValue (index: name: list.get listOfValues index) listOfNames
else
debug.panic "pair" "Names and Values must be two lists of same length!";
pairNameWithValue
= name: value: { inherit name value; };
partition
= predicate:
dictionary:
list.fold
(
{ right, wrong }:
name:
let
value = dictionary.${name};
in
if predicate name dictionary.${name}
then
{
inherit wrong;
right = right // { ${name} = value; };
}
else
{
inherit right;
wrong = wrong // { ${name} = value; };
}
)
{
right = {};
wrong = {};
}
(names dictionary);
partition'
= predicate:
partition (name: value: predicate { inherit name value; });
partitionByName
= predicate:
partition (name: _: predicate name);
partitionByValue
= predicate:
partition (_: predicate);
# { ... } -> [ string ] -> { ... }:
remove = intrinsics.removeAttrs;
# { T... } -> string -> T
# where T: Any:
select = { ... } @ self: field: self.${field};
select' = { ... } @ self: field: self.${field} or null;
selectOr = { ... } @ self: field: default: self.${field} or default;
values = intrinsics.attrValues;
zip = intrinsics.zipAttrsWith;
in
type "set"
{
isPrimitive = true;
of
= subtype:
let
inner = type.expect subtype;
in
type "SetOf"
{
isInstanceOf = value: isInstanceOf value && all (_: inner.isInstanceOf) value;
inherit inner;
};
inherit all all' any any'
callValues collect
filter filterByName filterKeys filterValue fold fold' foldValues
fromList fromListDefault fromListIMapped fromListIMappedValue fromListMapped fromListMappedValue
generate get getOr getKeySource getSource
hasAttribute
ifOrEmpty intersect isInstanceOf
map mapFold mapFold' mapNamesAndValues mapToList mapToListConcatted mapValues
name names
orNull
pair pairNameWithValue partition partitionByName partitionByValue
remove
select select' selectOr
values
zip;
}