about summary refs log tree commit diff
path: root/nix/yants
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-01-30T16·06+0300
committertazjin <tazjin@tvl.su>2022-01-31T16·11+0000
commitaa122cbae78ce97d60c0c98ba14df753d97e40b1 (patch)
tree12b98d85c4b18fe870feb26de70db9ba61837bd7 /nix/yants
parent2d10d60fac0fd00a71b65cfdcb9fba0477b2086c (diff)
style: format entire depot with nixpkgs-fmt r/3723
This CL can be used to compare the style of nixpkgs-fmt against other
formatters (nixpkgs, alejandra).

Change-Id: I87c6abff6bcb546b02ead15ad0405f81e01b6d9e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/4397
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: lukegb <lukegb@tvl.fyi>
Reviewed-by: wpcarro <wpcarro@gmail.com>
Reviewed-by: Profpatsch <mail@profpatsch.de>
Reviewed-by: kanepyork <rikingcoding@gmail.com>
Reviewed-by: tazjin <tazjin@tvl.su>
Reviewed-by: cynthia <cynthia@tvl.fyi>
Reviewed-by: edef <edef@edef.eu>
Reviewed-by: eta <tvl@eta.st>
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'nix/yants')
-rw-r--r--nix/yants/default.nix301
-rw-r--r--nix/yants/tests/default.nix34
2 files changed, 187 insertions, 148 deletions
diff --git a/nix/yants/default.nix b/nix/yants/default.nix
index 2bbf4dd15a9e..cb9fc08287fb 100644
--- a/nix/yants/default.nix
+++ b/nix/yants/default.nix
@@ -6,10 +6,10 @@
 #
 # All types (should) compose as expected.
 
-{ lib ?  (import <nixpkgs> {}).lib, ... }:
+{ lib ? (import <nixpkgs> { }).lib, ... }:
 
 with builtins; let
-  prettyPrint = lib.generators.toPretty {};
+  prettyPrint = lib.generators.toPretty { };
 
   # typedef' :: struct {
   #   name = string;
@@ -34,41 +34,44 @@ with builtins; let
   #
   # This function is the low-level primitive used to create types. For
   # many cases the higher-level 'typedef' function is more appropriate.
-  typedef' = { name, checkType
-             , checkToBool ? (result: result.ok)
-             , toError ? (_: result: result.err)
-             , def ? null
-             , match ? null }: {
-    inherit name checkToBool toError;
-
-    # check :: a -> bool
-    #
-    # This function is used to determine whether a given type is
-    # conformant.
-    check = value: checkToBool (checkType value);
-
-    # checkType :: a -> struct { ok = bool; err = option string; }
-    #
-    # This function checks whether the passed value is type conformant
-    # and returns an optional type error string otherwise.
-    inherit checkType;
-
-    # __functor :: a -> a
-    #
-    # This function checks whether the passed value is type conformant
-    # and throws an error if it is not.
-    #
-    # The name of this function is a special attribute in Nix that
-    # makes it possible to execute a type attribute set like a normal
-    # function.
-    __functor = self: value:
-    let result = self.checkType value;
-    in if checkToBool result then value
-       else throw (toError value result);
-  };
+  typedef' =
+    { name
+    , checkType
+    , checkToBool ? (result: result.ok)
+    , toError ? (_: result: result.err)
+    , def ? null
+    , match ? null
+    }: {
+      inherit name checkToBool toError;
+
+      # check :: a -> bool
+      #
+      # This function is used to determine whether a given type is
+      # conformant.
+      check = value: checkToBool (checkType value);
+
+      # checkType :: a -> struct { ok = bool; err = option string; }
+      #
+      # This function checks whether the passed value is type conformant
+      # and returns an optional type error string otherwise.
+      inherit checkType;
+
+      # __functor :: a -> a
+      #
+      # This function checks whether the passed value is type conformant
+      # and throws an error if it is not.
+      #
+      # The name of this function is a special attribute in Nix that
+      # makes it possible to execute a type attribute set like a normal
+      # function.
+      __functor = self: value:
+        let result = self.checkType value;
+        in if checkToBool result then value
+        else throw (toError value result);
+    };
 
   typeError = type: val:
-  "expected type '${type}', but value '${prettyPrint val}' is of type '${typeOf val}'";
+    "expected type '${type}', but value '${prettyPrint val}' is of type '${typeOf val}'";
 
   # typedef :: string -> (a -> bool) -> type
   #
@@ -85,27 +88,34 @@ with builtins; let
       });
   };
 
-  checkEach = name: t: l: foldl' (acc: e:
-    let res = t.checkType e;
+  checkEach = name: t: l: foldl'
+    (acc: e:
+      let
+        res = t.checkType e;
         isT = t.checkToBool res;
-    in {
-      ok = acc.ok && isT;
-      err = if isT
-        then acc.err
-        else acc.err + "${prettyPrint e}: ${t.toError e res}\n";
-    }) { ok = true; err = "expected type ${name}, but found:\n"; } l;
-in lib.fix (self: {
+      in
+      {
+        ok = acc.ok && isT;
+        err =
+          if isT
+          then acc.err
+          else acc.err + "${prettyPrint e}: ${t.toError e res}\n";
+      })
+    { ok = true; err = "expected type ${name}, but found:\n"; }
+    l;
+in
+lib.fix (self: {
   # Primitive types
-  any      = typedef "any" (_: true);
-  unit     = typedef "unit" (v: v == {});
-  int      = typedef "int" isInt;
-  bool     = typedef "bool" isBool;
-  float    = typedef "float" isFloat;
-  string   = typedef "string" isString;
-  path     = typedef "path" (x: typeOf x == "path");
-  drv      = typedef "derivation" (x: isAttrs x && x ? "type" && x.type == "derivation");
+  any = typedef "any" (_: true);
+  unit = typedef "unit" (v: v == { });
+  int = typedef "int" isInt;
+  bool = typedef "bool" isBool;
+  float = typedef "float" isFloat;
+  string = typedef "string" isString;
+  path = typedef "path" (x: typeOf x == "path");
+  drv = typedef "derivation" (x: isAttrs x && x ? "type" && x.type == "derivation");
   function = typedef "function" (x: isFunction x || (isAttrs x && x ? "__functor"
-                                                 && isFunction x.__functor));
+    && isFunction x.__functor));
 
   # Type for types themselves. Useful when defining polymorphic types.
   type = typedef "type" (x:
@@ -124,7 +134,7 @@ in lib.fix (self: {
       in {
         ok = isNull v || (self.type t).checkToBool res;
         err = "expected type ${name}, but value does not conform to '${t.name}': "
-         + t.toError v res;
+          + t.toError v res;
       };
   };
 
@@ -136,7 +146,8 @@ in lib.fix (self: {
   list = t: typedef' rec {
     name = "list<${t.name}>";
 
-    checkType = v: if isList v
+    checkType = v:
+      if isList v
       then checkEach name (self.type t) v
       else {
         ok = false;
@@ -147,7 +158,8 @@ in lib.fix (self: {
   attrs = t: typedef' rec {
     name = "attrs<${t.name}>";
 
-    checkType = v: if isAttrs v
+    checkType = v:
+      if isAttrs v
       then checkEach name (self.type t) (attrValues v)
       else {
         ok = false;
@@ -172,20 +184,23 @@ in lib.fix (self: {
       # checkField checks an individual field of the struct against
       # its definition and creates a typecheck result. These results
       # are aggregated during the actual checking.
-      checkField = def: name: value: let result = def.checkType value; in rec {
-        ok = def.checkToBool result;
-        err = if !ok && isNull value
-          then "missing required ${def.name} field '${name}'\n"
-          else "field '${name}': ${def.toError value result}\n";
-      };
+      checkField = def: name: value:
+        let result = def.checkType value; in rec {
+          ok = def.checkToBool result;
+          err =
+            if !ok && isNull value
+            then "missing required ${def.name} field '${name}'\n"
+            else "field '${name}': ${def.toError value result}\n";
+        };
 
       # checkExtraneous determines whether a (closed) struct contains
       # any fields that are not part of the definition.
       checkExtraneous = def: has: acc:
         if (length has) == 0 then acc
         else if (hasAttr (head has) def)
-          then checkExtraneous def (tail has) acc
-          else checkExtraneous def (tail has) {
+        then checkExtraneous def (tail has) acc
+        else
+          checkExtraneous def (tail has) {
             ok = false;
             err = acc.err + "unexpected struct field '${head has}'\n";
           };
@@ -197,85 +212,102 @@ in lib.fix (self: {
           init = { ok = true; err = ""; };
           extraneous = checkExtraneous def (attrNames value) init;
 
-          checkedFields = map (n:
-            let v = if hasAttr n value then value."${n}" else null;
-            in checkField def."${n}" n v) (attrNames def);
-
-          combined = foldl' (acc: res: {
-            ok = acc.ok && res.ok;
-            err = if !res.ok then acc.err + res.err else acc.err;
-          }) init checkedFields;
-        in {
+          checkedFields = map
+            (n:
+              let v = if hasAttr n value then value."${n}" else null;
+              in checkField def."${n}" n v)
+            (attrNames def);
+
+          combined = foldl'
+            (acc: res: {
+              ok = acc.ok && res.ok;
+              err = if !res.ok then acc.err + res.err else acc.err;
+            })
+            init
+            checkedFields;
+        in
+        {
           ok = combined.ok && extraneous.ok;
           err = combined.err + extraneous.err;
         };
 
       struct' = name: def: typedef' {
         inherit name def;
-        checkType = value: if isAttrs value
+        checkType = value:
+          if isAttrs value
           then (checkStruct (self.attrs self.type def) value)
           else { ok = false; err = typeError name value; };
 
-          toError = _: result: "expected '${name}'-struct, but found:\n" + result.err;
+        toError = _: result: "expected '${name}'-struct, but found:\n" + result.err;
       };
-    in arg: if isString arg then (struct' arg) else (struct' "anon" arg);
+    in
+    arg: if isString arg then (struct' arg) else (struct' "anon" arg);
 
   # Enums & pattern matching
   enum =
-  let
-    plain = name: def: typedef' {
-      inherit name def;
+    let
+      plain = name: def: typedef' {
+        inherit name def;
 
-      checkType = (x: isString x && elem x def);
-      checkToBool = x: x;
-      toError = value: _: "'${prettyPrint value} is not a member of enum ${name}";
-    };
-    enum' = name: def: lib.fix (e: (plain name def) // {
-      match = x: actions: deepSeq (map e (attrNames actions)) (
-      let
-        actionKeys = attrNames actions;
-        missing = foldl' (m: k: if (elem k actionKeys) then m else m ++ [ k ]) [] def;
-      in if (length missing) > 0
-        then throw "Missing match action for members: ${prettyPrint missing}"
-        else actions."${e x}");
-    });
-  in arg: if isString arg then (enum' arg) else (enum' "anon" arg);
+        checkType = (x: isString x && elem x def);
+        checkToBool = x: x;
+        toError = value: _: "'${prettyPrint value} is not a member of enum ${name}";
+      };
+      enum' = name: def: lib.fix (e: (plain name def) // {
+        match = x: actions: deepSeq (map e (attrNames actions)) (
+          let
+            actionKeys = attrNames actions;
+            missing = foldl' (m: k: if (elem k actionKeys) then m else m ++ [ k ]) [ ] def;
+          in
+          if (length missing) > 0
+          then throw "Missing match action for members: ${prettyPrint missing}"
+          else actions."${e x}"
+        );
+      });
+    in
+    arg: if isString arg then (enum' arg) else (enum' "anon" arg);
 
   # Sum types
   #
   # The representation of a sum type is an attribute set with only one
   # value, where the key of the value denotes the variant of the type.
   sum =
-  let
-    plain = name: def: typedef' {
-      inherit name def;
-      checkType = (x:
-        let variant = elemAt (attrNames x) 0;
-        in if isAttrs x && length (attrNames x) == 1 && hasAttr variant def
-          then let t = def."${variant}";
-                   v = x."${variant}";
-                   res = t.checkType v;
-               in if t.checkToBool res
-                  then { ok = true; }
-                  else {
-                    ok = false;
-                    err = "while checking '${name}' variant '${variant}': "
-                          + t.toError v res;
-                  }
+    let
+      plain = name: def: typedef' {
+        inherit name def;
+        checkType = (x:
+          let variant = elemAt (attrNames x) 0;
+          in if isAttrs x && length (attrNames x) == 1 && hasAttr variant def
+          then
+            let
+              t = def."${variant}";
+              v = x."${variant}";
+              res = t.checkType v;
+            in
+            if t.checkToBool res
+            then { ok = true; }
+            else {
+              ok = false;
+              err = "while checking '${name}' variant '${variant}': "
+                + t.toError v res;
+            }
           else { ok = false; err = typeError name x; }
-      );
-    };
-    sum' = name: def: lib.fix (s: (plain name def) // {
-    match = x: actions:
-    let variant = deepSeq (s x) (elemAt (attrNames x) 0);
-        actionKeys = attrNames actions;
-        defKeys = attrNames def;
-        missing = foldl' (m: k: if (elem k actionKeys) then m else m ++ [ k ]) [] defKeys;
-    in if (length missing) > 0
-      then throw "Missing match action for variants: ${prettyPrint missing}"
-      else actions."${variant}" x."${variant}";
-    });
-    in arg: if isString arg then (sum' arg) else (sum' "anon" arg);
+        );
+      };
+      sum' = name: def: lib.fix (s: (plain name def) // {
+        match = x: actions:
+          let
+            variant = deepSeq (s x) (elemAt (attrNames x) 0);
+            actionKeys = attrNames actions;
+            defKeys = attrNames def;
+            missing = foldl' (m: k: if (elem k actionKeys) then m else m ++ [ k ]) [ ] defKeys;
+          in
+          if (length missing) > 0
+          then throw "Missing match action for variants: ${prettyPrint missing}"
+          else actions."${variant}" x."${variant}";
+      });
+    in
+    arg: if isString arg then (sum' arg) else (sum' "anon" arg);
 
   # Typed function definitions
   #
@@ -289,15 +321,19 @@ in lib.fix (self: {
       mkFunc = sig: f: {
         inherit sig;
         __toString = self: foldl' (s: t: "${s} -> ${t.name}")
-                                  "λ :: ${(head self.sig).name}" (tail self.sig);
+          "λ :: ${(head self.sig).name}"
+          (tail self.sig);
         __functor = _: f;
       };
 
-      defun' = sig: func: if length sig > 2
+      defun' = sig: func:
+        if length sig > 2
         then mkFunc sig (x: defun' (tail sig) (func ((head sig) x)))
         else mkFunc sig (x: ((head (tail sig)) (func ((head sig) x))));
 
-    in sig: func: if length sig < 2
+    in
+    sig: func:
+      if length sig < 2
       then (throw "Signature must at least have two types (a -> b)")
       else defun' sig func;
 
@@ -311,21 +347,22 @@ in lib.fix (self: {
   # depend on the value being of the wrapped type.
   restrict = name: pred: t:
     let restriction = "${t.name}[${name}]"; in typedef' {
-    name = restriction;
-    checkType = v:
-      let res = t.checkType v;
-      in
+      name = restriction;
+      checkType = v:
+        let res = t.checkType v;
+        in
         if !(t.checkToBool res)
         then res
         else
           let
             iok = pred v;
-          in if isBool iok then {
+          in
+          if isBool iok then {
             ok = iok;
             err = "${prettyPrint v} does not conform to restriction '${restriction}'";
           } else
-            # use throw here to avoid spamming the build log
+          # use throw here to avoid spamming the build log
             throw "restriction '${restriction}' predicate returned unexpected value '${prettyPrint iok}' instead of boolean";
-  };
+    };
 
 })
diff --git a/nix/yants/tests/default.nix b/nix/yants/tests/default.nix
index 9a0b2403e124..0c7ec2418802 100644
--- a/nix/yants/tests/default.nix
+++ b/nix/yants/tests/default.nix
@@ -25,7 +25,7 @@ let
   };
 
   testPrimitives = it "checks that all primitive types match" [
-    (assertDoesNotThrow "unit type" (unit {}))
+    (assertDoesNotThrow "unit type" (unit { }))
     (assertDoesNotThrow "int type" (int 15))
     (assertDoesNotThrow "bool type" (bool false))
     (assertDoesNotThrow "float type" (float 13.37))
@@ -44,7 +44,7 @@ let
   # Test that structures work as planned.
   person = struct "person" {
     name = string;
-    age  = int;
+    age = int;
 
     contact = option (struct {
       email = string;
@@ -55,7 +55,7 @@ let
   testStruct = it "checks that structures work as intended" [
     (assertDoesNotThrow "person struct" (person {
       name = "Brynhjulf";
-      age  = 42;
+      age = 42;
       contact.email = "brynhjulf@yants.nix";
     }))
   ];
@@ -70,7 +70,8 @@ let
 
   testEnum = it "checks enum definitions and matching" [
     (assertEq "enum is matched correctly"
-      "It is in fact red!" (colour.match "red" colourMatcher))
+      "It is in fact red!"
+      (colour.match "red" colourMatcher))
     (assertThrows "out of bounds enum fails"
       (colour.match "alpha" (colourMatcher // {
         alpha = "This should never happen";
@@ -97,7 +98,8 @@ let
   testSum = it "checks sum types definitions and matching" [
     (assertDoesNotThrow "creature sum type" some-human)
     (assertEq "sum type is matched correctly"
-      "It's a human named Brynhjulf" (creature.match some-human {
+      "It's a human named Brynhjulf"
+      (creature.match some-human {
         human = v: "It's a human named ${v.name}";
         pet = v: "It's not supposed to be a pet!";
       })
@@ -106,7 +108,7 @@ let
 
   # Test curried function definitions
   func = defun [ string int string ]
-  (name: age: "${name} is ${toString age} years old");
+    (name: age: "${name} is ${toString age} years old");
 
   testFunctions = it "checks function definitions" [
     (assertDoesNotThrow "function application" (func "Brynhjulf" 42))
@@ -144,13 +146,13 @@ let
   ];
 
 in
-  runTestsuite "yants" [
-    testPrimitives
-    testPoly
-    testStruct
-    testEnum
-    testSum
-    testFunctions
-    testTypes
-    testRestrict
-  ]
+runTestsuite "yants" [
+  testPrimitives
+  testPoly
+  testStruct
+  testEnum
+  testSum
+  testFunctions
+  testTypes
+  testRestrict
+]