1# Cue (Cuelang) {#cuelang}
2
3[Cuelang](https://cuelang.org/) is a language to:
4
5- describe schemas and validate backward-compatibility
6- generate code and schemas in various formats (e.g. JSON Schema, OpenAPI)
7- do configuration akin to [Dhall Lang](https://dhall-lang.org/)
8- perform data validation
9
10## Cuelang schema quick start {#cuelang-quickstart}
11
12Cuelang schemas are similar to JSON, here is a quick cheatsheet:
13
14- Default types includes: `null`, `string`, `bool`, `bytes`, `number`, `int`, `float`, lists as `[...T]` where `T` is a type.
15- All structures, defined by: `myStructName: { <fields> }` are **open** -- they accept fields which are not specified.
16- Closed structures can be built by doing `myStructName: close({ <fields> })` -- they are strict in what they accept.
17- `#X` are **definitions**, referenced definitions are **recursively closed**, i.e. all its children structures are **closed**.
18- `&` operator is the [unification operator](https://cuelang.org/docs/references/spec/#unification) (similar to a type-level merging operator), `|` is the [disjunction operator](https://cuelang.org/docs/references/spec/#disjunction) (similar to a type-level union operator).
19- Values **are** types, i.e. `myStruct: { a: 3 }` is a valid type definition that only allows `3` as value.
20
21- Read <https://cuelang.org/docs/concepts/logic/> to learn more about the semantics.
22- Read <https://cuelang.org/docs/references/spec/> to learn about the language specification.
23
24## `writeCueValidator` {#cuelang-writeCueValidator}
25
26Nixpkgs provides a `pkgs.writeCueValidator` helper, which will write a validation script based on the provided Cuelang schema.
27
28Here is an example:
29```
30pkgs.writeCueValidator
31 (pkgs.writeText "schema.cue" ''
32 #Def1: {
33 field1: string
34 }
35 '')
36 { document = "#Def1"; }
37```
38
39- The first parameter is the Cue schema file.
40- The second parameter is an options parameter, currently, only: `document` can be passed.
41
42`document` : match your input data against this fragment of structure or definition, e.g. you may use the same schema file but different documents based on the data you are validating.
43
44Another example, given the following `validator.nix` :
45```
46{ pkgs ? import <nixpkgs> {} }:
47let
48 genericValidator = version:
49 pkgs.writeCueValidator
50 (pkgs.writeText "schema.cue" ''
51 #Version1: {
52 field1: string
53 }
54 #Version2: #Version1 & {
55 field1: "unused"
56 }''
57 )
58 { document = "#Version${toString version}"; };
59in
60{
61 validateV1 = genericValidator 1;
62 validateV2 = genericValidator 2;
63}
64```
65
66The result is a script that will validate the file you pass as the first argument against the schema you provided `writeCueValidator`.
67
68It can be any format that `cue vet` supports, i.e. YAML or JSON for example.
69
70Here is an example, named `example.json`, given the following JSON:
71```
72{ "field1": "abc" }
73```
74
75You can run the result script (named `validate`) as the following:
76
77```console
78$ nix-build validator.nix
79$ ./result example.json
80$ ./result-2 example.json
81field1: conflicting values "unused" and "abc":
82 ./example.json:1:13
83 ../../../../../../nix/store/v64dzx3vr3glpk0cq4hzmh450lrwh6sg-schema.cue:5:11
84$ sed -i 's/"abc"/3/' example.json
85$ ./result example.json
86field1: conflicting values 3 and string (mismatched types int and string):
87 ./example.json:1:13
88 ../../../../../../nix/store/v64dzx3vr3glpk0cq4hzmh450lrwh6sg-schema.cue:5:11
89```
90
91**Known limitations**
92
93* The script will enforce **concrete** values and will not accept lossy transformations (strictness). You can add these options if you need them.