The following introduces the basic building blocks in Cue.
Builtin Types
Cue has the following built in types.
They are meant to align with JSON types.
null bool string bytes number list struct
|
int
builtins.cue
N: nullB: boolS: stringBy: bytesNum: number// Decimals or integers, a superclass if you willInt: int// Big Int which can represent values without limitsList: [...]Struct: {...}
Top and Bottom
Top and Bottom are special values in Cue.
They form the opposite ends of the value lattice.
“_” is top and matches all value. It is also called the “any” value.
“_|_” is bottom and represents an error. (this symbol is likely to be replaced with a word in a future version)
Errors
Errors result in bottom with a message attached.
You can get errors for incomplete types when exporting Cue to data
or for conflicts and invalid semantics in your code.
errors.cue
s: "hello"s: "world"// conflicting values "hello" and "world"A: foo: "bar"a: A.goo // undefined field A.goo (cue eval -c)b: int// incomplete value (cue eval -c)l: [1, 2]l: [1, 3] // conflicting values 2 and 3m: [1, 2]v: m[2] // index out of range
cue eval -c errors.cue
l.1: conflicting values 3 and 2:
./errors.cue:7:7
./errors.cue:8:7
s: conflicting values "world" and "hello":
./errors.cue:1:4
./errors.cue:2:4
Null coalescing allows us to provide fallback values when errors occur.
This is technically error coalescing since null is a valid value.
This works by using disjunctions and defaults.
coalesce.cue
elems: ["a", "b", "c"]a: *elems[0] |"A"// out of bounds errord: *elems[3] |"D"S: { hello: "world"}// missing fieldss: *S.foo |"bar"
Cue strings are valid UTF-8 sequences with some escaping options
strings.cue
str: "hello world"smile: "\U0001F60A"quoted: "you can \"quote by escaping \\\""multiline: """ hello world a "quoted string in a string" down under - some author """
cue eval strings.cue
str: "hello world"smile: "😊"quoted: "you can \"quote by escaping \\\""multiline: """ hello world a "quoted string in a string" down under - some author """
The escape sequences are:
\a U+0007 alert or bell
\b U+0008 backspace
\f U+000C form feed
\n U+000A line feed or newline
\r U+000D carriage return
\t U+0009 horizontal tab
\v U+000b vertical tab
\/ U+002f slash (solidus)
\\ U+005c backslash
\' U+0027 single quote (valid escape only within single quoted literals)
\" U+0022 double quote (valid escape only within double quoted literals)
\nnn for octals (valid escape only within single quoted literals)
\xnn for hex (valid escape only within single quoted literals)
\uXXXX for unicode
\UXXXXXXXX for longer unicode
Structs are like JSON objects. They are the primary composite type in Cue.
They have a set of fields (label: value).
By default, they are open and you can add more fields.
structs.cue
// an open structa: { foo: "bar"}// shorthand nested fielda: hello: "world"// a closed structb: close({ left: "right"})// error, field up not allowedb: up: "down"
Definitions
Definitions are very similar to structs and are primarily used for schemas.
They are closed by default and are not emitted by Cue when exporting.
You can embed structs and definitions within each other as a method to build up values.
You can achieve the same with opened structs / definitions and conjunctions, but often we cannot modify what we can embed.
Pattern matching allows you to specify constraints for labels which match a pattern.
While limited in matching today, they will be significantly more powerful once the
query proposal is accepted and implemented.
For now, you can apply a constraint to string labels and use an identifier to set fields if you like.
patterns.cue
#schema: { name: string ans: string num: int|*42}// match elem fields and alias labels to Name,// unify with schema, set name to Name by labelelems: [Name=_]: #schema & {name: Name}elems: { one: { ans: "solo" num: 1 } two: { ans: "life" }}elems: other: {ans: "id", num: 23}