forked from
oeiuwq.com/den
Modular, context-aware and aspect-oriented dendritic Nix configurations.
Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/
1{
2 inputs,
3 lib,
4 config,
5 ...
6}:
7let
8
9 # "Just Give 'Em One of These" - Moe Szyslak
10 # A __functor that applies context to parametric includes (functions)
11 funk =
12 apply: aspect:
13 aspect
14 // {
15 __functor = self: ctx: {
16 includes = builtins.filter (x: x != { }) (map (apply ctx) (builtins.filter isFn self.includes));
17 };
18 };
19
20 isFn = f: (builtins.isFunction f) || (builtins.isAttrs f && f ? __functor);
21 canTake = import ./fn-can-take.nix lib;
22
23 # an aspect producing only owned configs
24 owned = (lib.flip builtins.removeAttrs) [
25 "includes"
26 "__functor"
27 ];
28
29 # only static includes from an aspect.
30 statics =
31 aspect:
32 aspect
33 // {
34 __functor =
35 self:
36 { class, aspect-chain }:
37 {
38 includes = map (applyStatics { inherit class aspect-chain; }) self.includes;
39 };
40 };
41
42 applyStatics =
43 ctx: f:
44 if !isFn f then
45 f
46 else if isStatic f && isCtxStatic ctx then
47 f ctx
48 else
49 { };
50
51 isStatic = canTake.atLeast {
52 class = "";
53 aspect-chain = [ ];
54 };
55 isCtxStatic = (lib.flip canTake.exactly) ({ class, aspect-chain }: class aspect-chain);
56
57 take.unused = _unused: used: used;
58 take.exactly = take canTake.exactly;
59 take.atLeast = take canTake.atLeast;
60 take.__functor =
61 _: takes: fn: ctx:
62 if takes ctx fn then fn ctx else { };
63
64 parametric.atLeast = funk (lib.flip take.atLeast);
65 parametric.exactly = funk (lib.flip take.exactly);
66 parametric.expands =
67 attrs: parametric.withOwn (aspect: ctx: parametric.atLeast aspect (ctx // attrs));
68 parametric.fixedTo =
69 attrs: aspect:
70 aspect
71 // {
72 __functor =
73 self:
74 { class, aspect-chain }:
75 {
76 includes = [
77 (owned self)
78 (statics self { inherit class aspect-chain; })
79 (parametric.atLeast self attrs)
80 ];
81 };
82 };
83 parametric.withOwn =
84 functor: aspect:
85 aspect
86 // {
87 __functor = self: ctx: {
88 includes =
89 if isCtxStatic ctx then
90 [
91 (owned self)
92 (statics self ctx)
93 ]
94 else
95 [ (functor self ctx) ];
96 };
97 };
98 parametric.__functor = _: parametric.withOwn parametric.atLeast;
99
100 aspects = inputs.flake-aspects.lib lib;
101
102 __findFile = import ./den-brackets.nix { inherit lib config; };
103
104 den-lib = {
105 inherit
106 parametric
107 aspects
108 __findFile
109 statics
110 owned
111 isFn
112 canTake
113 take
114 ;
115 };
116in
117den-lib