summaryrefslogtreecommitdiffstats
path: root/lib/types/custom.nix
blob: d25938bc9838248cf62df80fa8c02601a7717550 (plain)
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
{lib}: let
  inherit (builtins) toJSON attrNames;
  inherit (lib.options) mergeEqualOption;
  inherit (lib.lists) singleton;
  inherit (lib.strings) isString stringLength match;
  inherit (lib.types) listOf mkOptionType coercedTo enum;
  inherit (lib.trivial) warn;
in {
  mergelessListOf = elemType:
    mkOptionType {
      name = "mergelessListOf";
      description = "mergeless list of ${elemType.description or "values"}";
      inherit (lib.types.listOf elemType) check;
      merge = mergeEqualOption;
    };

  char = mkOptionType {
    name = "char";
    description = "character";
    descriptionClass = "noun";
    check = value: stringLength value < 2;
    merge = mergeEqualOption;
  };

  hexColor = mkOptionType {
    name = "hex-color";
    descriptionClass = "noun";
    description = "RGB color in hex format";
    check = v: isString v && (match "#?[0-9a-fA-F]{6}" v) != null;
  };

  # no compound types please
  deprecatedSingleOrListOf = option: t: let
    targetType = listOf t;
  in
    (coercedTo
      t
      (x:
        warn ''
          ${option} no longer accepts non-list values, use [${toJSON x}] instead
        ''
        (singleton x))
      targetType)
    // {inherit (targetType) description descriptionClass;};

  # Create an enum type for `values`, which additionally accepts deprecated
  # values listed in the `renames` attrset as `old = new` pairs.
  #
  # Example:
  #
  # vim.languages.typescript.lsp.servers = mkOption {
  #   type = enumWithRename
  #     "vim.languages.typescript.lsp.servers"
  #     ["typescript-language-server" "some-other-server"]
  #     { ts_ls = "typescript-language-server"; };
  # }
  #
  # With this option definition, when users enter `ts_ls`, they
  # get a warning "`ts_ls` is deprecated, use `typescript-language-server`
  # instead", and typescript-language-server is automatically used.
  enumWithRename = option: values: renames: let
    targetType = enum values;
  in
    (coercedTo (enum (attrNames renames)) (
        old:
          warn
          "${option}: `${old}` is deprecated, use `${renames.${old}}` instead"
          renames.${old}
      )
      targetType)
    // {inherit (targetType) description descriptionClass;};
}