about summary refs log tree commit diff
path: root/pkgs/stdenv/generic/meta-types.nix
blob: ddbd1daca696ea6d7cbcdb5b523501beb64a1a19 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
{ lib }:
# Simple internal type checks for meta.
# This file is not a stable interface and may be changed arbitrarily.
#
# TODO: add a method to the module system types
#       see https://github.com/NixOS/nixpkgs/pull/273935#issuecomment-1854173100
let
  inherit (builtins) isString isInt isAttrs isList all any attrValues isFunction isBool concatStringsSep isFloat;
  isTypeDef = t: isAttrs t && t ? name && isString t.name && t ? verify && isFunction t.verify;

in
lib.fix (self: {
  string = {
    name = "string";
    verify = isString;
  };
  str = self.string;  # Type alias

  any = {
    name = "any";
    verify = _: true;
  };

  int = {
    name = "int";
    verify = isInt;
  };

  float = {
    name = "float";
    verify = isFloat;
  };

  bool = {
    name = "bool";
    verify = isBool;
  };

  attrs = {
    name = "attrs";
    verify = isAttrs;
  };

  list = {
    name = "list";
    verify = isList;
  };

  attrsOf = t: assert isTypeDef t; let
    inherit (t) verify;
  in {
    name = "attrsOf<${t.name}>";
    verify =
      # attrsOf<any> can be optimised to just isAttrs
      if t == self.any then isAttrs
      else attrs: isAttrs attrs && all verify (attrValues attrs);
  };

  listOf = t: assert isTypeDef t; let
    inherit (t) verify;
  in {
    name = "listOf<${t.name}>";
    verify =
      # listOf<any> can be optimised to just isList
      if t == self.any then isList
      else v: isList v && all verify v;
  };

  union = types: assert all isTypeDef types; let
    # Store a list of functions so we don't have to pay the cost of attrset lookups at runtime.
    funcs = map (t: t.verify) types;
  in {
    name = "union<${concatStringsSep "," (map (t: t.name) types)}>";
    verify = v: any (func: func v) funcs;
  };
})