A tiny & fast composable type system for Nix, in Nix.
Named after the little penguin.
- Types
- Primitive types (
string
,int
, etc) - Polymorphic types (
union
,attrsOf
, etc) - Struct types
- Primitive types (
- Verification
Basic verification is done with the type function verify
:
{ korora }:
let
t = korora.string;
value = 1;
# Error contains the string "Expected type 'string' but value '1' is of type 'int'"
error = t.verify 1;
in if error != null then throw error else value
Errors are returned as a string.
On success null
is returned.
- Checking (assertions)
For convenience you can also check a value on-the-fly:
{ korora }:
let
t = korora.string;
value = 1;
# Same error as previous example, but `check` throws.
value = t.check value value;
in value
On error check
throws. On success it returns the value that was passed in.
For usage example see tests.nix.
Declare a custom type using a bool function.
name
: Name of the type as a string
verify
: Verification function returning a bool.
Declare a custom type using an option function.
name
: Name of the type as a string
verify
: Verification function returning null on success & a string with error message on error.
String
Type alias for string
Any
Never
Int
Single precision floating point
Either an int or a float
Bool
Attribute with undefined attribute types
Attribute with undefined element types
Function
Path
Derivation
Type
Option
t
: Null or t
listOf
t
: Element type
listOf
t
: Attribute value type
union<types...>
types
: Any of
intersection<types...>
types
: All of
struct<name, members...>
korora.struct "myStruct" {
foo = types.string;
}
- Totality
By default, all attribute names must be present in a struct. It is possible to override this by specifying totality. Here is how to do this:
(korora.struct "myStruct" {
foo = types.string;
}).override { total = false; }
This means that a myStruct
struct can have any of the keys omitted. Thus these are valid:
let
s1 = { };
s2 = { foo = "bar"; }
in ...
- Unknown attribute names
By default, unknown attribute names are allowed.
It is possible to override this by specifying unknown
.
(korora.struct "myStruct" {
foo = types.string;
}).override { unknown = false; }
This means that
{
foo = "bar";
baz = "hello";
}
is normally valid, but not when unknown
is set to false
.
Because Nix lacks primitive operations to iterate over attribute sets dynamically without allocation this function allocates one intermediate attribute set per struct verification.
- Custom invariants
Custom struct verification functions can be added as such:
(types.struct "testStruct2" {
x = types.int;
y = types.int;
}).override {
verify = v: if v.x + v.y == 2 then "VERBOTEN" else null;
};
name
: Name of struct type as a string
members
: Attribute set of type definitions.
enum<name, elems...>
name
: Name of enum type as a string
elems
: List of allowable enum members