fake.modules transposition for aspect-oriented Dendritic Nix. with cross-aspect dependencies. Discussions: https://oeiuwq.zulipchat.com/join/nqp26cd4kngon6mo3ncgnuap/ dendrix.oeiuwq.com/Dendritic.html
dendritic nix aspect oriented

provider args must be named

+26 -12
+6 -7
checkmate.nix
··· 246 246 flake.aspects = 247 247 { aspects, ... }: 248 248 { 249 - aspectOne.includes = [ (aspects.aspectTwo.provides.hello "mundo") ]; 249 + aspectOne.includes = [ (aspects.aspectTwo.provides.hello { world = "mundo"; }) ]; 250 250 aspectOne.classOne.bar = [ "1" ]; 251 251 252 252 aspectTwo.provides.hello = 253 - world: 254 - # deadnix: skip 255 - { aspect-chain, class }: 256 - { 253 + { world }: # args must always be named. 254 + _: { 257 255 classOne.bar = [ world ]; 258 256 }; 259 257 }; ··· 275 273 flake.aspects = 276 274 { aspects, ... }: 277 275 { 278 - aspectOne.includes = [ (aspects.aspectTwo "hello") ]; 276 + aspectOne.includes = [ (aspects.aspectTwo { message = "hello"; }) ]; 279 277 aspectOne.classOne = { }; # required for propagation 280 278 281 279 aspectTwo.__functor = 282 - _: message: 280 + _: 281 + { message }: # args must be always named 283 282 { class, aspect-chain }: 284 283 { aspect, ... }: 285 284 {
+20 -5
nix/types.nix
··· 2 2 let 3 3 4 4 aspectsType = lib.types.submodule { 5 - freeformType = lib.types.lazyAttrsOf aspectSubmodule; 5 + freeformType = lib.types.attrsOf aspectSubmodule; 6 6 }; 7 7 8 - providerType = lib.types.functionTo aspectSubmodule; 8 + functionToAspect = lib.types.addCheck (lib.types.functionTo aspectSubmodule) ( 9 + f: 10 + let 11 + args = lib.functionArgs f; 12 + arity = lib.length (lib.attrNames args); 13 + isEmpty = arity == 0; 14 + hasClass = args ? class; 15 + hasChain = args ? aspect-chain; 16 + classOnly = hasClass && arity == 1; 17 + chainOnly = hasChain && arity == 1; 18 + both = hasClass && hasChain && arity == 2; 19 + in 20 + isEmpty || classOnly || chainOnly || both 21 + ); 22 + 23 + providerType = lib.types.either functionToAspect (lib.types.functionTo providerType); 9 24 10 25 aspectSubmodule = aspectSubmoduleWithModules [ ]; 11 26 ··· 22 37 ... 23 38 }: 24 39 { 25 - freeformType = lib.types.lazyAttrsOf lib.types.deferredModule; 40 + freeformType = lib.types.attrsOf lib.types.deferredModule; 26 41 config._module.args.aspect = config; 27 42 options.name = lib.mkOption { 28 43 description = "Aspect name"; ··· 45 60 type = lib.types.submodule ( 46 61 { config, ... }: 47 62 { 48 - freeformType = lib.types.lazyAttrsOf (lib.types.functionTo lib.types.unspecified); 63 + freeformType = lib.types.attrsOf providerType; 49 64 config._module.args.provides = config; 50 65 options.itself = lib.mkOption { 51 66 readOnly = true; ··· 60 75 internal = true; 61 76 visible = false; 62 77 description = "Functor to default provider"; 63 - type = lib.types.functionTo lib.types.unspecified; 78 + type = lib.types.functionTo providerType; 64 79 default = _: aspect.provides.itself; 65 80 }; 66 81 }