From 23696ba46c7c48a2c1e99c68c4b247a12b49ecd0 Mon Sep 17 00:00:00 2001 From: Jonathan Matthews Date: Tue, 31 Oct 2023 11:34:37 +0000 Subject: [PATCH] docs/tour: import cuelang.org/docs/tutorials/tour/types/ This change imports the contents of https://cuelang.org/docs/tutorials/tour/types/ into /docs/tour/types/. Minimal formatting changes have been made, to align content with alpha's preprocessor and hugo capabilities, with the following exception: - the faux-table in content/docs/tour/types/bounddef/en.md has had ":" added at the end of each line's "field names", to allow the file to be treated as CUE instead of the source's raw text. This allows the content to be formatted automatically. The overall delta from the source material is shown by this shell command: for PAGE in types bottom numbers stringlit stringraw bytes closed defs optional disjunctions defaults sumstruct bounds bounddef lists templates ; do git diff 4b2c4880862e096ea38517da3c6a938b434581bf:content/en/docs/tutorials/tour/types/$PAGE.md content/docs/tour/types/$PAGE/en.md; done A sub-optimal method is used for replicating the side-by-side layout of the existing tour when the command that's executed needs to be displayed (as it's not a simple `cue eval` or `cue export`). This is documented, with a nicer/preprocessor solution requested, in cue-lang/cue#2667 For cue-lang/docs-and-content#25 Preview-Path: /docs/tour/types/ Change-Id: I47c8bb624b364691396d2162a0e83d69140d72d2 Signed-off-by: Jonathan Matthews Dispatch-Trailer: {"type":"trybot","CL":1171469,"patchset":2,"ref":"refs/changes/69/1171469/2","targetBranch":"alpha"} --- content/docs/tour/types/_en.md | 9 +++ content/docs/tour/types/bottom/en.md | 34 +++++++++ content/docs/tour/types/bottom/gen_cache.cue | 20 ++++++ content/docs/tour/types/bottom/page.cue | 3 + content/docs/tour/types/bounddef/en.md | 43 ++++++++++++ .../docs/tour/types/bounddef/gen_cache.cue | 21 ++++++ content/docs/tour/types/bounddef/page.cue | 3 + content/docs/tour/types/bounds/en.md | 39 +++++++++++ content/docs/tour/types/bounds/gen_cache.cue | 20 ++++++ content/docs/tour/types/bounds/page.cue | 3 + content/docs/tour/types/bytes/en.md | 24 +++++++ content/docs/tour/types/bytes/gen_cache.cue | 21 ++++++ content/docs/tour/types/bytes/page.cue | 3 + content/docs/tour/types/closed/en.md | 35 ++++++++++ content/docs/tour/types/closed/gen_cache.cue | 20 ++++++ content/docs/tour/types/closed/page.cue | 3 + content/docs/tour/types/defaults/en.md | 27 +++++++ .../docs/tour/types/defaults/gen_cache.cue | 20 ++++++ content/docs/tour/types/defaults/page.cue | 3 + content/docs/tour/types/defs/en.md | 36 ++++++++++ content/docs/tour/types/defs/gen_cache.cue | 20 ++++++ content/docs/tour/types/defs/page.cue | 3 + content/docs/tour/types/disjunctions/en.md | 36 ++++++++++ .../tour/types/disjunctions/gen_cache.cue | 20 ++++++ content/docs/tour/types/disjunctions/page.cue | 3 + content/docs/tour/types/lists/en.md | 44 ++++++++++++ content/docs/tour/types/lists/gen_cache.cue | 20 ++++++ content/docs/tour/types/lists/page.cue | 3 + content/docs/tour/types/numbers/en.md | 44 ++++++++++++ content/docs/tour/types/numbers/gen_cache.cue | 20 ++++++ content/docs/tour/types/numbers/page.cue | 3 + content/docs/tour/types/optional/en.md | 34 +++++++++ .../docs/tour/types/optional/gen_cache.cue | 20 ++++++ content/docs/tour/types/optional/page.cue | 3 + content/docs/tour/types/page.cue | 3 + content/docs/tour/types/stringlit/en.md | 33 +++++++++ .../docs/tour/types/stringlit/gen_cache.cue | 20 ++++++ content/docs/tour/types/stringlit/page.cue | 3 + content/docs/tour/types/stringraw/en.md | 35 ++++++++++ .../docs/tour/types/stringraw/gen_cache.cue | 20 ++++++ content/docs/tour/types/stringraw/page.cue | 3 + content/docs/tour/types/sumstruct/en.md | 28 ++++++++ .../docs/tour/types/sumstruct/gen_cache.cue | 20 ++++++ content/docs/tour/types/sumstruct/page.cue | 3 + content/docs/tour/types/templates/en.md | 49 +++++++++++++ .../docs/tour/types/templates/gen_cache.cue | 20 ++++++ content/docs/tour/types/templates/page.cue | 3 + content/docs/tour/types/types/en.md | 69 ++++++++++++++++++ content/docs/tour/types/types/gen_cache.cue | 21 ++++++ content/docs/tour/types/types/page.cue | 3 + hugo/content/en/docs/tour/types/_index.md | 9 +++ .../en/docs/tour/types/bottom/index.md | 34 +++++++++ .../en/docs/tour/types/bounddef/index.md | 42 +++++++++++ .../en/docs/tour/types/bounds/index.md | 39 +++++++++++ .../content/en/docs/tour/types/bytes/index.md | 25 +++++++ .../en/docs/tour/types/closed/index.md | 35 ++++++++++ .../en/docs/tour/types/defaults/index.md | 28 ++++++++ hugo/content/en/docs/tour/types/defs/index.md | 36 ++++++++++ .../en/docs/tour/types/disjunctions/index.md | 38 ++++++++++ .../content/en/docs/tour/types/lists/index.md | 44 ++++++++++++ .../en/docs/tour/types/numbers/index.md | 44 ++++++++++++ .../en/docs/tour/types/optional/index.md | 34 +++++++++ .../en/docs/tour/types/stringlit/index.md | 34 +++++++++ .../en/docs/tour/types/stringraw/index.md | 37 ++++++++++ .../en/docs/tour/types/sumstruct/index.md | 26 +++++++ .../en/docs/tour/types/templates/index.md | 50 +++++++++++++ .../content/en/docs/tour/types/types/index.md | 70 +++++++++++++++++++ 67 files changed, 1618 insertions(+) create mode 100644 content/docs/tour/types/_en.md create mode 100644 content/docs/tour/types/bottom/en.md create mode 100644 content/docs/tour/types/bottom/gen_cache.cue create mode 100644 content/docs/tour/types/bottom/page.cue create mode 100644 content/docs/tour/types/bounddef/en.md create mode 100644 content/docs/tour/types/bounddef/gen_cache.cue create mode 100644 content/docs/tour/types/bounddef/page.cue create mode 100644 content/docs/tour/types/bounds/en.md create mode 100644 content/docs/tour/types/bounds/gen_cache.cue create mode 100644 content/docs/tour/types/bounds/page.cue create mode 100644 content/docs/tour/types/bytes/en.md create mode 100644 content/docs/tour/types/bytes/gen_cache.cue create mode 100644 content/docs/tour/types/bytes/page.cue create mode 100644 content/docs/tour/types/closed/en.md create mode 100644 content/docs/tour/types/closed/gen_cache.cue create mode 100644 content/docs/tour/types/closed/page.cue create mode 100644 content/docs/tour/types/defaults/en.md create mode 100644 content/docs/tour/types/defaults/gen_cache.cue create mode 100644 content/docs/tour/types/defaults/page.cue create mode 100644 content/docs/tour/types/defs/en.md create mode 100644 content/docs/tour/types/defs/gen_cache.cue create mode 100644 content/docs/tour/types/defs/page.cue create mode 100644 content/docs/tour/types/disjunctions/en.md create mode 100644 content/docs/tour/types/disjunctions/gen_cache.cue create mode 100644 content/docs/tour/types/disjunctions/page.cue create mode 100644 content/docs/tour/types/lists/en.md create mode 100644 content/docs/tour/types/lists/gen_cache.cue create mode 100644 content/docs/tour/types/lists/page.cue create mode 100644 content/docs/tour/types/numbers/en.md create mode 100644 content/docs/tour/types/numbers/gen_cache.cue create mode 100644 content/docs/tour/types/numbers/page.cue create mode 100644 content/docs/tour/types/optional/en.md create mode 100644 content/docs/tour/types/optional/gen_cache.cue create mode 100644 content/docs/tour/types/optional/page.cue create mode 100644 content/docs/tour/types/page.cue create mode 100644 content/docs/tour/types/stringlit/en.md create mode 100644 content/docs/tour/types/stringlit/gen_cache.cue create mode 100644 content/docs/tour/types/stringlit/page.cue create mode 100644 content/docs/tour/types/stringraw/en.md create mode 100644 content/docs/tour/types/stringraw/gen_cache.cue create mode 100644 content/docs/tour/types/stringraw/page.cue create mode 100644 content/docs/tour/types/sumstruct/en.md create mode 100644 content/docs/tour/types/sumstruct/gen_cache.cue create mode 100644 content/docs/tour/types/sumstruct/page.cue create mode 100644 content/docs/tour/types/templates/en.md create mode 100644 content/docs/tour/types/templates/gen_cache.cue create mode 100644 content/docs/tour/types/templates/page.cue create mode 100644 content/docs/tour/types/types/en.md create mode 100644 content/docs/tour/types/types/gen_cache.cue create mode 100644 content/docs/tour/types/types/page.cue create mode 100644 hugo/content/en/docs/tour/types/_index.md create mode 100644 hugo/content/en/docs/tour/types/bottom/index.md create mode 100644 hugo/content/en/docs/tour/types/bounddef/index.md create mode 100644 hugo/content/en/docs/tour/types/bounds/index.md create mode 100644 hugo/content/en/docs/tour/types/bytes/index.md create mode 100644 hugo/content/en/docs/tour/types/closed/index.md create mode 100644 hugo/content/en/docs/tour/types/defaults/index.md create mode 100644 hugo/content/en/docs/tour/types/defs/index.md create mode 100644 hugo/content/en/docs/tour/types/disjunctions/index.md create mode 100644 hugo/content/en/docs/tour/types/lists/index.md create mode 100644 hugo/content/en/docs/tour/types/numbers/index.md create mode 100644 hugo/content/en/docs/tour/types/optional/index.md create mode 100644 hugo/content/en/docs/tour/types/stringlit/index.md create mode 100644 hugo/content/en/docs/tour/types/stringraw/index.md create mode 100644 hugo/content/en/docs/tour/types/sumstruct/index.md create mode 100644 hugo/content/en/docs/tour/types/templates/index.md create mode 100644 hugo/content/en/docs/tour/types/types/index.md diff --git a/content/docs/tour/types/_en.md b/content/docs/tour/types/_en.md new file mode 100644 index 0000000000..b529b78b29 --- /dev/null +++ b/content/docs/tour/types/_en.md @@ -0,0 +1,9 @@ +--- +title: "Types and Values" +--- + +This tour demonstrates the hierarchy of primitive and complex types that CUE +makes available, along with common methods for constraining and combining these +types. + +## Contents diff --git a/content/docs/tour/types/bottom/en.md b/content/docs/tour/types/bottom/en.md new file mode 100644 index 0000000000..83f7c44262 --- /dev/null +++ b/content/docs/tour/types/bottom/en.md @@ -0,0 +1,34 @@ +--- +title: "Bottom / Error" +weight: 2 +--- +Specifying duplicate fields with conflicting values results in an error +or bottom. +_Bottom_ is a special value in CUE, denoted `_|_`, that indicates an +error such as conflicting values. +Any error in CUE results in `_|_`. +Logically all errors are equal, although errors may be associated with +metadata such as an error message. + +Note that an error is different from `null`: `null` is a valid value, +whereas `_|_` is not. + +{{{with code "en" "bottom"}}} +exec cue eval -i bottom.cue +cmp stdout '$ cue eval -i bottom.cue' +-- bottom.cue -- +a: 4 +a: 5 + +l: [ 1, 2] +l: [ 1, 3] + +list: [0, 1, 2] +val: list[3] +-- $ cue eval -i bottom.cue -- +a: _|_ // a: conflicting values 5 and 4 +l: [1, _|_, // l.1: conflicting values 3 and 2 +] +list: [0, 1, 2] +val: _|_ // val: index out of range [3] with length 3 +{{{end}}} diff --git a/content/docs/tour/types/bottom/gen_cache.cue b/content/docs/tour/types/bottom/gen_cache.cue new file mode 100644 index 0000000000..d96f790af2 --- /dev/null +++ b/content/docs/tour/types/bottom/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + bottom: { + page: { + cache: { + code: { + bottom: "nVWmtoCwxo2MltMzeeFZCXDasDDlZM7LFe6yfnQG1SU=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/bottom/page.cue b/content/docs/tour/types/bottom/page.cue new file mode 100644 index 0000000000..87107a377a --- /dev/null +++ b/content/docs/tour/types/bottom/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: bottom: {} diff --git a/content/docs/tour/types/bounddef/en.md b/content/docs/tour/types/bounddef/en.md new file mode 100644 index 0000000000..c7afb0ac7e --- /dev/null +++ b/content/docs/tour/types/bounddef/en.md @@ -0,0 +1,43 @@ +--- +title: "Predefined Bounds" +weight: 14 +--- +CUE numbers have arbitrary precision. +Also there is no unsigned integer type. + +CUE defines the following predefined identifiers to restrict the bounds of +integers to common values. + +{{{with code "en" "defined"}}} +-- in.cue -- +uint: >=0 +uint8: >=0 & <=255 +int8: >=-128 & <=127 +uint16: >=0 & <=65536 +int16: >=-32_768 & <=32_767 +rune: >=0 & <=0x10FFFF +uint32: >=0 & <=4_294_967_296 +int32: >=-2_147_483_648 & <=2_147_483_647 +uint64: >=0 & <=18_446_744_073_709_551_615 +int64: >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807 +int128: >=-170_141_183_460_469_231_731_687_303_715_884_105_728 & + <=170_141_183_460_469_231_731_687_303_715_884_105_727 +uint128: >=0 & <=340_282_366_920_938_463_463_374_607_431_768_211_455 +{{{end}}} + +{{{with code "en" "failure"}}} +exec cue eval -ic bound.cue +cmp stdout '$ cue eval -ic bound.cue' +-- bound.cue -- +#positive: uint +#byte: uint8 +#word: int32 + +a: #positive & -1 +b: #byte & 128 +c: #word & 2_000_000_000 +-- $ cue eval -ic bound.cue -- +a: _|_ // a: invalid value -1 (out of bound >=0) +b: 128 +c: 2000000000 +{{{end}}} diff --git a/content/docs/tour/types/bounddef/gen_cache.cue b/content/docs/tour/types/bounddef/gen_cache.cue new file mode 100644 index 0000000000..d1c4f96f42 --- /dev/null +++ b/content/docs/tour/types/bounddef/gen_cache.cue @@ -0,0 +1,21 @@ +package site +{ + content: { + docs: { + tour: { + types: { + bounddef: { + page: { + cache: { + code: { + defined: "MohhkFjPJDw6JacZKpy05dq6V7IvtCjcSRoAeVyZzOQ=" + failure: "HvILLQ/uSPtoJEAq/x+mzGPoWMXdigD18sCAU9YwMIg=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/bounddef/page.cue b/content/docs/tour/types/bounddef/page.cue new file mode 100644 index 0000000000..89fca800b2 --- /dev/null +++ b/content/docs/tour/types/bounddef/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: bounddef: {} diff --git a/content/docs/tour/types/bounds/en.md b/content/docs/tour/types/bounds/en.md new file mode 100644 index 0000000000..c52e29e68f --- /dev/null +++ b/content/docs/tour/types/bounds/en.md @@ -0,0 +1,39 @@ +--- +title: "Bounds" +weight: 13 +--- +Bounds define a lower bound, upper bound, or inequality for a certain value. +They work on numbers, strings, bytes and null. + +The bound is defined for all values for which the corresponding comparison +operation is defined. +For instance `>5.0` allows all floating point values greater than `5.0`, +whereas `<0` allows all negative numbers (int or float). + + +{{{with code "en" "failure"}}} +exec cue eval -ic bounds.cue +cmp stdout '$ cue eval -ic bounds.cue' +-- bounds.cue -- +#rn: >=3 & <8 // type int | float + +#ri: >=3 & <8 & int // type int + +#rf: >=3 & <=8.0 // type float +#rs: >="a" & <"mo" + +a: #rn & 3.5 +b: #ri & 3.5 +c: #rf & 3 +d: #rs & "ma" +e: #rs & "mu" + +r1: #rn & >=5 & <10 +-- $ cue eval -ic bounds.cue -- +a: 3.5 +b: _|_ // b: conflicting values int and 3.5 (mismatched types int and float) +c: 3 +d: "ma" +e: _|_ // e: invalid value "mu" (out of bound <"mo") +r1: >=5 & <8 +{{{end}}} diff --git a/content/docs/tour/types/bounds/gen_cache.cue b/content/docs/tour/types/bounds/gen_cache.cue new file mode 100644 index 0000000000..b01c2497f2 --- /dev/null +++ b/content/docs/tour/types/bounds/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + bounds: { + page: { + cache: { + code: { + failure: "i2XOqSgd0R4pfPqroxbF1GW311kDl7jEuSD1Ax4gNTY=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/bounds/page.cue b/content/docs/tour/types/bounds/page.cue new file mode 100644 index 0000000000..16ee31148b --- /dev/null +++ b/content/docs/tour/types/bounds/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: bounds: {} diff --git a/content/docs/tour/types/bytes/en.md b/content/docs/tour/types/bytes/en.md new file mode 100644 index 0000000000..841bc42204 --- /dev/null +++ b/content/docs/tour/types/bytes/en.md @@ -0,0 +1,24 @@ +--- +title: "Bytes" +weight: 6 +--- +CUE distinguishes between a `string` and a `bytes` type. +Bytes are converted to base64 when emitting JSON. +Byte literals are defined with single quotes. +The following additional escape sequences are allowed in byte literals: + +{{{with code "en" "escapes"}}} +-- in.txt -- + \xnn // arbitrary byte value defined as a 2-digit hexadecimal number + \nnn // arbitrary byte value defined as a 3-digit octal number +{{{end}}} + + +{{{with code "en" "bytes"}}} +-- in.cue -- +a: '\x03abc' +-- out.json -- +{ + "a": "A2FiYw==" +} +{{{end}}} diff --git a/content/docs/tour/types/bytes/gen_cache.cue b/content/docs/tour/types/bytes/gen_cache.cue new file mode 100644 index 0000000000..f23cce6523 --- /dev/null +++ b/content/docs/tour/types/bytes/gen_cache.cue @@ -0,0 +1,21 @@ +package site +{ + content: { + docs: { + tour: { + types: { + bytes: { + page: { + cache: { + code: { + escapes: "8vtA7ViI2sFYm8xmKowJXMB5ndr3JrCrE1tYBSagbyY=" + bytes: "/VCm4S2hcboOQNMR4h3VBDKFP2jW6AREcy5wdBCnWkc=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/bytes/page.cue b/content/docs/tour/types/bytes/page.cue new file mode 100644 index 0000000000..0450d8a114 --- /dev/null +++ b/content/docs/tour/types/bytes/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: bytes: {} diff --git a/content/docs/tour/types/closed/en.md b/content/docs/tour/types/closed/en.md new file mode 100644 index 0000000000..ffabbb7e0b --- /dev/null +++ b/content/docs/tour/types/closed/en.md @@ -0,0 +1,35 @@ +--- +title: "Closed structs" +weight: 7 +--- +Struct is the most important composite type in CUE. + +A struct may be open or closed. +A closed struct may only be merged with structs that have fields that +it defines to be allowed. +In other words, closing a struct is equivalent to requiring that all +other values be undefined. + +A closed struct can be created using the `close` builtin, +but are more commonly defined using a _definition_, defined next. + +{{{with code "en" "structs"}}} +exec cue eval -i structs.cue +cmp stdout '$ cue eval -i structs.cue' +-- structs.cue -- +a: close({ + field: int +}) + +b: a & { + feild: 3 +} +-- $ cue eval -i structs.cue -- +a: { + field: int +} +b: { + field: int + feild: _|_ // b.feild: field not allowed +} +{{{end}}} diff --git a/content/docs/tour/types/closed/gen_cache.cue b/content/docs/tour/types/closed/gen_cache.cue new file mode 100644 index 0000000000..489de3ab8a --- /dev/null +++ b/content/docs/tour/types/closed/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + closed: { + page: { + cache: { + code: { + structs: "5IUiLlZhc0s9SnEL9/LM8hFFJhAIWaR2G2SdH7i+yDI=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/closed/page.cue b/content/docs/tour/types/closed/page.cue new file mode 100644 index 0000000000..e1998b5cdf --- /dev/null +++ b/content/docs/tour/types/closed/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: closed: {} diff --git a/content/docs/tour/types/defaults/en.md b/content/docs/tour/types/defaults/en.md new file mode 100644 index 0000000000..7f65a7ebff --- /dev/null +++ b/content/docs/tour/types/defaults/en.md @@ -0,0 +1,27 @@ +--- +title: "Default Values" +weight: 11 +--- +Elements of a disjunction may be marked as preferred. +If there is only one mark, or the users constraints a field enough such that +only one mark remains, that value is the default value. + +In the example, `replicas` defaults to `1`. +In the case of `protocol`, however, there are multiple definitions with +different, mutually incompatible defaults. +In that case, both `"tcp"` and `"udp"` are preferred and one must explicitly +specify either `"tcp"` or `"udp"` as if no marks were given. + +{{{with code "en" "defaults"}}} +#nofmt(in.cue) https://github.com/cue-lang/cue/issues/722 +-- in.cue -- +// any positive number, 1 is the default +replicas: uint | *1 + +// the default value is ambiguous +protocol: *"tcp" | "udp" +protocol: *"udp" | "tcp" +-- out.cue -- +replicas: 1 +protocol: "tcp" | "udp" +{{{end}}} diff --git a/content/docs/tour/types/defaults/gen_cache.cue b/content/docs/tour/types/defaults/gen_cache.cue new file mode 100644 index 0000000000..b41a8ccd55 --- /dev/null +++ b/content/docs/tour/types/defaults/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + defaults: { + page: { + cache: { + code: { + defaults: "GYWvuj2K32SEjbWwJoXXWPynXA6rQz9Y7aC/802wPYU=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/defaults/page.cue b/content/docs/tour/types/defaults/page.cue new file mode 100644 index 0000000000..424ea9691e --- /dev/null +++ b/content/docs/tour/types/defaults/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: defaults: {} diff --git a/content/docs/tour/types/defs/en.md b/content/docs/tour/types/defs/en.md new file mode 100644 index 0000000000..a96f3db481 --- /dev/null +++ b/content/docs/tour/types/defs/en.md @@ -0,0 +1,36 @@ +--- +title: "Definitions" +weight: 8 +--- +A definition, indicated by an identifier starting with `#` or `_#`, +defines values that +are not output when converting a configuration to a concrete value. +They are used to define schema against which concrete values can +be validated. + +Structs defined by definitions are implicitly closed. + +{{{with code "en" "definitions"}}} +exec cue eval -ic defs.cue +cmp stdout '$ cue eval -ic defs.cue' +-- defs.cue -- +msg: "Hello \(#Name)!" + +#Name: "world" + +#A: { + field: int +} + +a: #A & {field: 3} +err: #A & {feild: 3} +-- $ cue eval -ic defs.cue -- +msg: "Hello world!" +a: { + field: 3 +} +err: { + field: int + feild: _|_ // err.feild: field not allowed +} +{{{end}}} diff --git a/content/docs/tour/types/defs/gen_cache.cue b/content/docs/tour/types/defs/gen_cache.cue new file mode 100644 index 0000000000..3da41b8e5d --- /dev/null +++ b/content/docs/tour/types/defs/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + defs: { + page: { + cache: { + code: { + definitions: "HvBicFp6ea1IbgYL/AnUUHGd+QLcKmzGWACUyG2vAqw=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/defs/page.cue b/content/docs/tour/types/defs/page.cue new file mode 100644 index 0000000000..af473e3010 --- /dev/null +++ b/content/docs/tour/types/defs/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: defs: {} diff --git a/content/docs/tour/types/disjunctions/en.md b/content/docs/tour/types/disjunctions/en.md new file mode 100644 index 0000000000..9a6121fffc --- /dev/null +++ b/content/docs/tour/types/disjunctions/en.md @@ -0,0 +1,36 @@ +--- +title: "Disjunctions" +weight: 10 +--- +Disjunctions, or sum types, define a new type that is one of several things. + +In the example, our `Conn` definition of earlier is augmented to define +the possible values for `protocol`: `"tcp"` or `"udp"`. +It is an error for a concrete `Conn` +to define anything else than these two values. + +{{{with code "en" "disjunctions"}}} +-- in.cue -- +#Conn: { + address: string + port: int + protocol: "tcp" | "udp" +} + +lossy: #Conn & { + address: "1.2.3.4" + port: 8888 + protocol: "udp" +} +-- out.cue -- +#Conn: { + address: string + port: int + protocol: "tcp" | "udp" +} +lossy: { + address: "1.2.3.4" + port: 8888 + protocol: "udp" +} +{{{end}}} diff --git a/content/docs/tour/types/disjunctions/gen_cache.cue b/content/docs/tour/types/disjunctions/gen_cache.cue new file mode 100644 index 0000000000..fa6eee326d --- /dev/null +++ b/content/docs/tour/types/disjunctions/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + disjunctions: { + page: { + cache: { + code: { + disjunctions: "Oj2iLfJe3aY3Tpmi9KhBZ8Ox9h7PMCJUN6ZhcvSxFL0=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/disjunctions/page.cue b/content/docs/tour/types/disjunctions/page.cue new file mode 100644 index 0000000000..beff323ee3 --- /dev/null +++ b/content/docs/tour/types/disjunctions/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: disjunctions: {} diff --git a/content/docs/tour/types/lists/en.md b/content/docs/tour/types/lists/en.md new file mode 100644 index 0000000000..6fb445102a --- /dev/null +++ b/content/docs/tour/types/lists/en.md @@ -0,0 +1,44 @@ +--- +title: "Lists" +weight: 15 +--- +Lists define arbitrary sequences of CUE values. +A list can be closed or open ended. +Open-ended lists may have some predefined elements, but may have +additional, possibly typed elements. + +In the example we define `IP` to be a list of `4` elements of type `uint8`, which +is a predeclared value of `>=0 & <=255`. +`PrivateIP` defines the IP ranges defined for private use. +Note that as it is already defined to be an `IP`, the length of the list +is already fixed at `4` and we do not have to specify a value for all elements. +Also note that instead of writing `...uint8`, we could have written `...` +as the type constraint is already implied by `IP`. + +The output contains a valid private IP address (`myIP`) +and an invalid one (`yourIP`). + +{{{with code "en" "lists"}}} +exec cue eval -i lists.cue +cmp stdout '$ cue eval -i lists.cue' +-- lists.cue -- +import "list" + +IP: list.Repeat([ uint8], 4) + +PrivateIP: IP +PrivateIP: [10, ...uint8] | + [192, 168, ...] | + [172, >=16 & <=32, ...] + +myIP: PrivateIP +myIP: [10, 2, 3, 4] + +yourIP: PrivateIP +yourIP: [11, 1, 2, 3] +-- $ cue eval -i lists.cue -- +IP: [uint8, uint8, uint8, uint8] +PrivateIP: [10, uint8, uint8, uint8] | [192, 168, uint8, uint8] | [172, uint & >=16 & <=32, uint8, uint8] +myIP: [10, 2, 3, 4] +yourIP: _|_ // yourIP: 3 errors in empty disjunction: (and 3 more errors) +{{{end}}} diff --git a/content/docs/tour/types/lists/gen_cache.cue b/content/docs/tour/types/lists/gen_cache.cue new file mode 100644 index 0000000000..7ecf6c2f85 --- /dev/null +++ b/content/docs/tour/types/lists/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + lists: { + page: { + cache: { + code: { + lists: "pdG2OyTdDyfCmtaFmU/Qbk26uHYBngSgADHNd8Q+8qo=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/lists/page.cue b/content/docs/tour/types/lists/page.cue new file mode 100644 index 0000000000..6bb7c50076 --- /dev/null +++ b/content/docs/tour/types/lists/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: lists: {} diff --git a/content/docs/tour/types/numbers/en.md b/content/docs/tour/types/numbers/en.md new file mode 100644 index 0000000000..51ee6b3447 --- /dev/null +++ b/content/docs/tour/types/numbers/en.md @@ -0,0 +1,44 @@ +--- +title: "Numbers" +weight: 3 +--- +CUE defines two kinds of numbers. +Integers, denoted `int`, are whole, or integral, numbers. +Floats, denoted `float`, are decimal floating point numbers. + +An integer literal (e.g. `4`) can be of either type, but defaults to `int`. +A floating point literal (e.g. `4.0`) is only compatible with `float`. + +In the example, the result of `b` is a `float` and cannot be +used as an `int` without conversion. + +CUE also adds a variety of sugar for writing numbers. + +{{{with code "en" "number"}}} +exec cue eval -i numbers.cue +cmp stdout '$ cue eval -i numbers.cue' +-- numbers.cue -- +a: int +a: 4 // type int + +b: number +b: 4.0 // type float + +c: int +c: 4.0 + +d: 4 // will evaluate to type int (default) + +e: [ + 1_234, // 1234 + 5M, // 5_000_000 + 1.5Gi, // 1_610_612_736 + 0x1000_0000, // 268_435_456 +] +-- $ cue eval -i numbers.cue -- +a: 4 +b: 4.0 +c: _|_ // c: conflicting values int and 4.0 (mismatched types int and float) +d: 4 +e: [1_234, 5M, 1.5Gi, 0x1000_0000] +{{{end}}} diff --git a/content/docs/tour/types/numbers/gen_cache.cue b/content/docs/tour/types/numbers/gen_cache.cue new file mode 100644 index 0000000000..8578b2eab1 --- /dev/null +++ b/content/docs/tour/types/numbers/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + numbers: { + page: { + cache: { + code: { + number: "2knZKTvYPnDO1mFix1LHpipX2IKgJLjq0QkuA04VOb4=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/numbers/page.cue b/content/docs/tour/types/numbers/page.cue new file mode 100644 index 0000000000..ea7c272b13 --- /dev/null +++ b/content/docs/tour/types/numbers/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: numbers: {} diff --git a/content/docs/tour/types/optional/en.md b/content/docs/tour/types/optional/en.md new file mode 100644 index 0000000000..3d641ae389 --- /dev/null +++ b/content/docs/tour/types/optional/en.md @@ -0,0 +1,34 @@ +--- +title: "Structs" +weight: 9 +--- +Struct is the most important composite type in CUE. +Its members are called fields. + +A struct field may be optional. +One can use an optional field to indicate what the type should be if it were +specified. +A regular (or required) field, on the other hand, must be made concrete +for a configuration to be converted to, say, JSON. + +It is okay for an optional field to be bottom (`_|_`). +This just means that field may not be specified. + +{{{with code "en" "structs"}}} +exec cue eval -c structs.cue +cmp stdout '$ cue eval -c structs.cue' +-- structs.cue -- +#a: { + foo?: int + bar?: string + baz?: string +} +b: #a & { + foo: 3 + baz?: 2 // baz?: _|_ +} +-- $ cue eval -c structs.cue -- +b: { + foo: 3 +} +{{{end}}} diff --git a/content/docs/tour/types/optional/gen_cache.cue b/content/docs/tour/types/optional/gen_cache.cue new file mode 100644 index 0000000000..2bfdfbda5b --- /dev/null +++ b/content/docs/tour/types/optional/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + optional: { + page: { + cache: { + code: { + structs: "BfhnEjKLPjJdDngtz4i9pbNhL12CUS9r7jxM6UOuuGc=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/optional/page.cue b/content/docs/tour/types/optional/page.cue new file mode 100644 index 0000000000..9fdc9b43e2 --- /dev/null +++ b/content/docs/tour/types/optional/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: optional: {} diff --git a/content/docs/tour/types/page.cue b/content/docs/tour/types/page.cue new file mode 100644 index 0000000000..44ef04e868 --- /dev/null +++ b/content/docs/tour/types/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: {} diff --git a/content/docs/tour/types/stringlit/en.md b/content/docs/tour/types/stringlit/en.md new file mode 100644 index 0000000000..51fb3c8dcb --- /dev/null +++ b/content/docs/tour/types/stringlit/en.md @@ -0,0 +1,33 @@ +--- +title: "String Literals" +weight: 4 +--- +CUE strings allow a richer set of escape sequences than JSON. + +CUE also supports multi-line strings, enclosed by a pair of triple quotes `"""`. +The opening quote must be followed by a newline. +The closing quote must also be on a newline. +The whitespace directly preceding the closing quote must match the preceding +whitespace on all other lines and is removed from these lines. + +Strings may also contain [interpolations](../../expressions/interpolation). + + + +{{{with code "en" "stringlit"}}} +#nofmt(in.cue) https://github.com/cue-lang/cue/issues/722 +-- in.cue -- +// 21-bit unicode characters +a: "\U0001F60E" // 😎 + +// multiline strings +b: """ + Hello + World! + """ +-- out.json -- +{ + "a": "😎", + "b": "Hello\nWorld!" +} +{{{end}}} diff --git a/content/docs/tour/types/stringlit/gen_cache.cue b/content/docs/tour/types/stringlit/gen_cache.cue new file mode 100644 index 0000000000..83c1a76a7a --- /dev/null +++ b/content/docs/tour/types/stringlit/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + stringlit: { + page: { + cache: { + code: { + stringlit: "qIYnlrmW5oSliq3lZsE7szarDkS2O8S9HBiQCpk26bo=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/stringlit/page.cue b/content/docs/tour/types/stringlit/page.cue new file mode 100644 index 0000000000..fe172b3a56 --- /dev/null +++ b/content/docs/tour/types/stringlit/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: stringlit: {} diff --git a/content/docs/tour/types/stringraw/en.md b/content/docs/tour/types/stringraw/en.md new file mode 100644 index 0000000000..a280a5fb3f --- /dev/null +++ b/content/docs/tour/types/stringraw/en.md @@ -0,0 +1,35 @@ +--- +title: "\"Raw\" Strings" +weight: 5 +--- +CUE does not support raw strings in the strictest sense. +Instead it allows modifying the escape delimiter by requiring +an arbitrary number of hash `#` signs after the backslash by +enclosing a string literal in an equal number of hash signs on either end. + +This works for normal and interpolated strings. +Quotes do not have to be escaped in such strings. + +{{{with code "en" "raw"}}} +-- in.cue -- +msg1: #"The sequence "\U0001F604" renders as \#U0001F604."# + +msg2: ##""" + A regular expression can conveniently be written as: + + #"\d{3}"# + + This construct works for bytes, strings and their + multi-line variants. + """## +-- out.cue -- +msg1: "The sequence \"\\U0001F604\" renders as 😄." +msg2: """ + A regular expression can conveniently be written as: + + #"\\d{3}"# + + This construct works for bytes, strings and their + multi-line variants. + """ +{{{end}}} diff --git a/content/docs/tour/types/stringraw/gen_cache.cue b/content/docs/tour/types/stringraw/gen_cache.cue new file mode 100644 index 0000000000..70a6c9c0bf --- /dev/null +++ b/content/docs/tour/types/stringraw/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + stringraw: { + page: { + cache: { + code: { + raw: "U0gchBeRzURZ5cCrRnDHOIAQuXyzDYOAfQ7aJCE1Cx8=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/stringraw/page.cue b/content/docs/tour/types/stringraw/page.cue new file mode 100644 index 0000000000..e864cf8406 --- /dev/null +++ b/content/docs/tour/types/stringraw/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: stringraw: {} diff --git a/content/docs/tour/types/sumstruct/en.md b/content/docs/tour/types/sumstruct/en.md new file mode 100644 index 0000000000..6d87549f33 --- /dev/null +++ b/content/docs/tour/types/sumstruct/en.md @@ -0,0 +1,28 @@ +--- +title: "Disjunctions of Structs" +weight: 12 +--- +Disjunctions work for any type. + +In this example we see that a `floor` of some specific house +has an exit on level 0 and 1, but not on any other floor. + + +{{{with code "en" "example"}}} +#nofmt(in.cue) https://github.com/cue-lang/cue/issues/722 +-- in.cue -- +// floor defines the specs of a floor in some house. +floor: { + level: int // the level on which this floor resides + hasExit: bool // is there a door to exit the house? +} + +// constraints on the possible values of floor. +floor: { + level: 0 | 1 + hasExit: true +} | { + level: -1 | 2 | 3 + hasExit: false +} +{{{end}}} diff --git a/content/docs/tour/types/sumstruct/gen_cache.cue b/content/docs/tour/types/sumstruct/gen_cache.cue new file mode 100644 index 0000000000..e20408f548 --- /dev/null +++ b/content/docs/tour/types/sumstruct/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + sumstruct: { + page: { + cache: { + code: { + example: "Dta9a8iiMAlQqK4iCev5FdEUO2vhDkbsq6aJGpM3ZvM=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/sumstruct/page.cue b/content/docs/tour/types/sumstruct/page.cue new file mode 100644 index 0000000000..8a06f6a23f --- /dev/null +++ b/content/docs/tour/types/sumstruct/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: sumstruct: {} diff --git a/content/docs/tour/types/templates/en.md b/content/docs/tour/types/templates/en.md new file mode 100644 index 0000000000..399ebde2b2 --- /dev/null +++ b/content/docs/tour/types/templates/en.md @@ -0,0 +1,49 @@ +--- +title: "Templates" +weight: 16 +--- +One of CUE's most powerful features is the ability +to specify optional fields in bulk. +This allows one to specify constraints, +or templates, +to be unified with each field of a struct. + +An optional field set is an expression in square brackets +to specify to which fields to apply a constraint +(currently only `string`, or all fields is supported). +Using an alias in the square brackets binds the +label of the matched field to the given identifier, +which can then be used within the template. + + +{{{with code "en" "templates"}}} +#nofmt(in.cue) https://github.com/cue-lang/cue/issues/722 +-- in.cue -- +// The following struct is unified with all elements in job. +// The name of each element is bound to Name and visible in the struct. +job: [Name=_]: { + name: Name + replicas: uint | *1 + command: string +} + +job: list: command: "ls" + +job: nginx: { + command: "nginx" + replicas: 2 +} +-- out.cue -- +job: { + list: { + name: "list" + replicas: 1 + command: "ls" + } + nginx: { + name: "nginx" + command: "nginx" + replicas: 2 + } +} +{{{end}}} diff --git a/content/docs/tour/types/templates/gen_cache.cue b/content/docs/tour/types/templates/gen_cache.cue new file mode 100644 index 0000000000..5dc0d522f4 --- /dev/null +++ b/content/docs/tour/types/templates/gen_cache.cue @@ -0,0 +1,20 @@ +package site +{ + content: { + docs: { + tour: { + types: { + templates: { + page: { + cache: { + code: { + templates: "k4RzZr75Fd5nMTu1wU2sRHkK7indjqBU7/Wf6AaBdzk=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/templates/page.cue b/content/docs/tour/types/templates/page.cue new file mode 100644 index 0000000000..c15061b992 --- /dev/null +++ b/content/docs/tour/types/templates/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: templates: {} diff --git a/content/docs/tour/types/types/en.md b/content/docs/tour/types/types/en.md new file mode 100644 index 0000000000..6db5c44cad --- /dev/null +++ b/content/docs/tour/types/types/en.md @@ -0,0 +1,69 @@ +--- +title: "Type Hierarchy" +weight: 1 +--- +CUE defines the following type hierarchy + +{{{with code "en" "hierarchy"}}} +-- in.txt -- + null bool string bytes number struct list + / \ + int float +{{{end}}} + +In addition, CUE defines the values +bottom, or error, (denoted `_|_`) +that is an instance of all types and +top, or any, (denoted `_`) of which all types are an instance. + +Note how we use the terms types and values interchangeably. +CUE does not distinguish between types and values. +The term "type" merely refers to the kind of a value, +which may or may not be a concrete instance. + +In the example, `point` defines an arbitrary point, while `xaxis` and `yaxis` +define the points on the respective lines. +We say that `point`, `xaxis`, and `yaxis` are incomplete, +as they do not specify a specific point. +Incomplete values cannot be represented as JSON, +as it can only represent concrete values. + +The only concrete point is `origin`. +The `origin` is defined to be both on the x-axis and y-axis, which means it +must be at `0, 0`. +Here we see constraints in action: +`origin` evalutes to `0, 0`, even though we did not specify its coordinates +explicitly. + +{{{with code "en" "point"}}} +-- in.cue -- +point: { + x: number + y: number +} + +xaxis: point +xaxis: y: 0 + +yaxis: point +yaxis: x: 0 + +origin: xaxis & yaxis +-- out.cue -- +point: { + x: number + y: number +} +xaxis: { + x: number + y: 0 +} +yaxis: { + x: 0 + y: number +} +origin: { + x: 0 + y: 0 +} +{{{end}}} diff --git a/content/docs/tour/types/types/gen_cache.cue b/content/docs/tour/types/types/gen_cache.cue new file mode 100644 index 0000000000..b628dd9372 --- /dev/null +++ b/content/docs/tour/types/types/gen_cache.cue @@ -0,0 +1,21 @@ +package site +{ + content: { + docs: { + tour: { + types: { + types: { + page: { + cache: { + code: { + hierarchy: "O0e9JEn9KKwEX2IL0CYB+3fuh3U6YCHQrs376Vgq+l8=" + point: "CP9iVPF3mFvBtbsKFTmuDus8GwAvTsUojOpgftiV3vA=" + } + } + } + } + } + } + } + } +} diff --git a/content/docs/tour/types/types/page.cue b/content/docs/tour/types/types/page.cue new file mode 100644 index 0000000000..d507bb46a6 --- /dev/null +++ b/content/docs/tour/types/types/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: tour: types: types: {} diff --git a/hugo/content/en/docs/tour/types/_index.md b/hugo/content/en/docs/tour/types/_index.md new file mode 100644 index 0000000000..b529b78b29 --- /dev/null +++ b/hugo/content/en/docs/tour/types/_index.md @@ -0,0 +1,9 @@ +--- +title: "Types and Values" +--- + +This tour demonstrates the hierarchy of primitive and complex types that CUE +makes available, along with common methods for constraining and combining these +types. + +## Contents diff --git a/hugo/content/en/docs/tour/types/bottom/index.md b/hugo/content/en/docs/tour/types/bottom/index.md new file mode 100644 index 0000000000..71da544915 --- /dev/null +++ b/hugo/content/en/docs/tour/types/bottom/index.md @@ -0,0 +1,34 @@ +--- +title: "Bottom / Error" +weight: 2 +--- +Specifying duplicate fields with conflicting values results in an error +or bottom. +_Bottom_ is a special value in CUE, denoted `_|_`, that indicates an +error such as conflicting values. +Any error in CUE results in `_|_`. +Logically all errors are equal, although errors may be associated with +metadata such as an error message. + +Note that an error is different from `null`: `null` is a valid value, +whereas `_|_` is not. + +{{< code-tabs >}} +{{< code-tab name="bottom.cue" language="text" area="top-left" >}} +a: 4 +a: 5 + +l: [ 1, 2] +l: [ 1, 3] + +list: [0, 1, 2] +val: list[3] +{{< /code-tab >}} +{{< code-tab name="$ cue eval -i bottom.cue" language="text" area="top-right" >}} +a: _|_ // a: conflicting values 5 and 4 +l: [1, _|_, // l.1: conflicting values 3 and 2 +] +list: [0, 1, 2] +val: _|_ // val: index out of range [3] with length 3 +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/bounddef/index.md b/hugo/content/en/docs/tour/types/bounddef/index.md new file mode 100644 index 0000000000..34fae75c33 --- /dev/null +++ b/hugo/content/en/docs/tour/types/bounddef/index.md @@ -0,0 +1,42 @@ +--- +title: "Predefined Bounds" +weight: 14 +--- +CUE numbers have arbitrary precision. +Also there is no unsigned integer type. + +CUE defines the following predefined identifiers to restrict the bounds of +integers to common values. + +```text +uint: >=0 +uint8: >=0 & <=255 +int8: >=-128 & <=127 +uint16: >=0 & <=65536 +int16: >=-32_768 & <=32_767 +rune: >=0 & <=0x10FFFF +uint32: >=0 & <=4_294_967_296 +int32: >=-2_147_483_648 & <=2_147_483_647 +uint64: >=0 & <=18_446_744_073_709_551_615 +int64: >=-9_223_372_036_854_775_808 & <=9_223_372_036_854_775_807 +int128: >=-170_141_183_460_469_231_731_687_303_715_884_105_728 & + <=170_141_183_460_469_231_731_687_303_715_884_105_727 +uint128: >=0 & <=340_282_366_920_938_463_463_374_607_431_768_211_455 +``` + +{{< code-tabs >}} +{{< code-tab name="bound.cue" language="text" area="top-left" >}} +#positive: uint +#byte: uint8 +#word: int32 + +a: #positive & -1 +b: #byte & 128 +c: #word & 2_000_000_000 +{{< /code-tab >}} +{{< code-tab name="$ cue eval -ic bound.cue" language="text" area="top-right" >}} +a: _|_ // a: invalid value -1 (out of bound >=0) +b: 128 +c: 2000000000 +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/bounds/index.md b/hugo/content/en/docs/tour/types/bounds/index.md new file mode 100644 index 0000000000..aab55851af --- /dev/null +++ b/hugo/content/en/docs/tour/types/bounds/index.md @@ -0,0 +1,39 @@ +--- +title: "Bounds" +weight: 13 +--- +Bounds define a lower bound, upper bound, or inequality for a certain value. +They work on numbers, strings, bytes and null. + +The bound is defined for all values for which the corresponding comparison +operation is defined. +For instance `>5.0` allows all floating point values greater than `5.0`, +whereas `<0` allows all negative numbers (int or float). + + +{{< code-tabs >}} +{{< code-tab name="bounds.cue" language="text" area="top-left" >}} +#rn: >=3 & <8 // type int | float + +#ri: >=3 & <8 & int // type int + +#rf: >=3 & <=8.0 // type float +#rs: >="a" & <"mo" + +a: #rn & 3.5 +b: #ri & 3.5 +c: #rf & 3 +d: #rs & "ma" +e: #rs & "mu" + +r1: #rn & >=5 & <10 +{{< /code-tab >}} +{{< code-tab name="$ cue eval -ic bounds.cue" language="text" area="top-right" >}} +a: 3.5 +b: _|_ // b: conflicting values int and 3.5 (mismatched types int and float) +c: 3 +d: "ma" +e: _|_ // e: invalid value "mu" (out of bound <"mo") +r1: >=5 & <8 +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/bytes/index.md b/hugo/content/en/docs/tour/types/bytes/index.md new file mode 100644 index 0000000000..b9e288e877 --- /dev/null +++ b/hugo/content/en/docs/tour/types/bytes/index.md @@ -0,0 +1,25 @@ +--- +title: "Bytes" +weight: 6 +--- +CUE distinguishes between a `string` and a `bytes` type. +Bytes are converted to base64 when emitting JSON. +Byte literals are defined with single quotes. +The following additional escape sequences are allowed in byte literals: + +```txt + \xnn // arbitrary byte value defined as a 2-digit hexadecimal number + \nnn // arbitrary byte value defined as a 3-digit octal number +``` + + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +a: '\x03abc' +{{< /code-tab >}} +{{< code-tab name="JSON" language="json" type="terminal" area="top-right" >}} +{ + "a": "A2FiYw==" +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/closed/index.md b/hugo/content/en/docs/tour/types/closed/index.md new file mode 100644 index 0000000000..29d4ef369d --- /dev/null +++ b/hugo/content/en/docs/tour/types/closed/index.md @@ -0,0 +1,35 @@ +--- +title: "Closed structs" +weight: 7 +--- +Struct is the most important composite type in CUE. + +A struct may be open or closed. +A closed struct may only be merged with structs that have fields that +it defines to be allowed. +In other words, closing a struct is equivalent to requiring that all +other values be undefined. + +A closed struct can be created using the `close` builtin, +but are more commonly defined using a _definition_, defined next. + +{{< code-tabs >}} +{{< code-tab name="structs.cue" language="text" area="top-left" >}} +a: close({ + field: int +}) + +b: a & { + feild: 3 +} +{{< /code-tab >}} +{{< code-tab name="$ cue eval -i structs.cue" language="text" area="top-right" >}} +a: { + field: int +} +b: { + field: int + feild: _|_ // b.feild: field not allowed +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/defaults/index.md b/hugo/content/en/docs/tour/types/defaults/index.md new file mode 100644 index 0000000000..8ed4ebff5a --- /dev/null +++ b/hugo/content/en/docs/tour/types/defaults/index.md @@ -0,0 +1,28 @@ +--- +title: "Default Values" +weight: 11 +--- +Elements of a disjunction may be marked as preferred. +If there is only one mark, or the users constraints a field enough such that +only one mark remains, that value is the default value. + +In the example, `replicas` defaults to `1`. +In the case of `protocol`, however, there are multiple definitions with +different, mutually incompatible defaults. +In that case, both `"tcp"` and `"udp"` are preferred and one must explicitly +specify either `"tcp"` or `"udp"` as if no marks were given. + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +// any positive number, 1 is the default +replicas: uint | *1 + +// the default value is ambiguous +protocol: *"tcp" | "udp" +protocol: *"udp" | "tcp" +{{< /code-tab >}} +{{< code-tab name="CUE" language="text" type="terminal" area="top-right" >}} +replicas: 1 +protocol: "tcp" | "udp" +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/defs/index.md b/hugo/content/en/docs/tour/types/defs/index.md new file mode 100644 index 0000000000..ff78e12d11 --- /dev/null +++ b/hugo/content/en/docs/tour/types/defs/index.md @@ -0,0 +1,36 @@ +--- +title: "Definitions" +weight: 8 +--- +A definition, indicated by an identifier starting with `#` or `_#`, +defines values that +are not output when converting a configuration to a concrete value. +They are used to define schema against which concrete values can +be validated. + +Structs defined by definitions are implicitly closed. + +{{< code-tabs >}} +{{< code-tab name="defs.cue" language="text" area="top-left" >}} +msg: "Hello \(#Name)!" + +#Name: "world" + +#A: { + field: int +} + +a: #A & {field: 3} +err: #A & {feild: 3} +{{< /code-tab >}} +{{< code-tab name="$ cue eval -ic defs.cue" language="text" area="top-right" >}} +msg: "Hello world!" +a: { + field: 3 +} +err: { + field: int + feild: _|_ // err.feild: field not allowed +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/disjunctions/index.md b/hugo/content/en/docs/tour/types/disjunctions/index.md new file mode 100644 index 0000000000..bd27aa7aff --- /dev/null +++ b/hugo/content/en/docs/tour/types/disjunctions/index.md @@ -0,0 +1,38 @@ +--- +title: "Disjunctions" +weight: 10 +--- +Disjunctions, or sum types, define a new type that is one of several things. + +In the example, our `Conn` definition of earlier is augmented to define +the possible values for `protocol`: `"tcp"` or `"udp"`. +It is an error for a concrete `Conn` +to define anything else than these two values. + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +#Conn: { + address: string + port: int + protocol: "tcp" | "udp" +} + +lossy: #Conn & { + address: "1.2.3.4" + port: 8888 + protocol: "udp" +} +{{< /code-tab >}} +{{< code-tab name="CUE" language="text" type="terminal" area="top-right" >}} +#Conn: { + address: string + port: int + protocol: "tcp" | "udp" +} +lossy: { + address: "1.2.3.4" + port: 8888 + protocol: "udp" +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/lists/index.md b/hugo/content/en/docs/tour/types/lists/index.md new file mode 100644 index 0000000000..7faa920309 --- /dev/null +++ b/hugo/content/en/docs/tour/types/lists/index.md @@ -0,0 +1,44 @@ +--- +title: "Lists" +weight: 15 +--- +Lists define arbitrary sequences of CUE values. +A list can be closed or open ended. +Open-ended lists may have some predefined elements, but may have +additional, possibly typed elements. + +In the example we define `IP` to be a list of `4` elements of type `uint8`, which +is a predeclared value of `>=0 & <=255`. +`PrivateIP` defines the IP ranges defined for private use. +Note that as it is already defined to be an `IP`, the length of the list +is already fixed at `4` and we do not have to specify a value for all elements. +Also note that instead of writing `...uint8`, we could have written `...` +as the type constraint is already implied by `IP`. + +The output contains a valid private IP address (`myIP`) +and an invalid one (`yourIP`). + +{{< code-tabs >}} +{{< code-tab name="lists.cue" language="text" area="top-left" >}} +import "list" + +IP: list.Repeat([ uint8], 4) + +PrivateIP: IP +PrivateIP: [10, ...uint8] | + [192, 168, ...] | + [172, >=16 & <=32, ...] + +myIP: PrivateIP +myIP: [10, 2, 3, 4] + +yourIP: PrivateIP +yourIP: [11, 1, 2, 3] +{{< /code-tab >}} +{{< code-tab name="$ cue eval -i lists.cue" language="text" area="top-right" >}} +IP: [uint8, uint8, uint8, uint8] +PrivateIP: [10, uint8, uint8, uint8] | [192, 168, uint8, uint8] | [172, uint & >=16 & <=32, uint8, uint8] +myIP: [10, 2, 3, 4] +yourIP: _|_ // yourIP: 3 errors in empty disjunction: (and 3 more errors) +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/numbers/index.md b/hugo/content/en/docs/tour/types/numbers/index.md new file mode 100644 index 0000000000..36e09943ce --- /dev/null +++ b/hugo/content/en/docs/tour/types/numbers/index.md @@ -0,0 +1,44 @@ +--- +title: "Numbers" +weight: 3 +--- +CUE defines two kinds of numbers. +Integers, denoted `int`, are whole, or integral, numbers. +Floats, denoted `float`, are decimal floating point numbers. + +An integer literal (e.g. `4`) can be of either type, but defaults to `int`. +A floating point literal (e.g. `4.0`) is only compatible with `float`. + +In the example, the result of `b` is a `float` and cannot be +used as an `int` without conversion. + +CUE also adds a variety of sugar for writing numbers. + +{{< code-tabs >}} +{{< code-tab name="numbers.cue" language="text" area="top-left" >}} +a: int +a: 4 // type int + +b: number +b: 4.0 // type float + +c: int +c: 4.0 + +d: 4 // will evaluate to type int (default) + +e: [ + 1_234, // 1234 + 5M, // 5_000_000 + 1.5Gi, // 1_610_612_736 + 0x1000_0000, // 268_435_456 +] +{{< /code-tab >}} +{{< code-tab name="$ cue eval -i numbers.cue" language="text" area="top-right" >}} +a: 4 +b: 4.0 +c: _|_ // c: conflicting values int and 4.0 (mismatched types int and float) +d: 4 +e: [1_234, 5M, 1.5Gi, 0x1000_0000] +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/optional/index.md b/hugo/content/en/docs/tour/types/optional/index.md new file mode 100644 index 0000000000..fdf1d2159f --- /dev/null +++ b/hugo/content/en/docs/tour/types/optional/index.md @@ -0,0 +1,34 @@ +--- +title: "Structs" +weight: 9 +--- +Struct is the most important composite type in CUE. +Its members are called fields. + +A struct field may be optional. +One can use an optional field to indicate what the type should be if it were +specified. +A regular (or required) field, on the other hand, must be made concrete +for a configuration to be converted to, say, JSON. + +It is okay for an optional field to be bottom (`_|_`). +This just means that field may not be specified. + +{{< code-tabs >}} +{{< code-tab name="structs.cue" language="text" area="top-left" >}} +#a: { + foo?: int + bar?: string + baz?: string +} +b: #a & { + foo: 3 + baz?: 2 // baz?: _|_ +} +{{< /code-tab >}} +{{< code-tab name="$ cue eval -c structs.cue" language="text" area="top-right" >}} +b: { + foo: 3 +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/stringlit/index.md b/hugo/content/en/docs/tour/types/stringlit/index.md new file mode 100644 index 0000000000..cb8c7e26f8 --- /dev/null +++ b/hugo/content/en/docs/tour/types/stringlit/index.md @@ -0,0 +1,34 @@ +--- +title: "String Literals" +weight: 4 +--- +CUE strings allow a richer set of escape sequences than JSON. + +CUE also supports multi-line strings, enclosed by a pair of triple quotes `"""`. +The opening quote must be followed by a newline. +The closing quote must also be on a newline. +The whitespace directly preceding the closing quote must match the preceding +whitespace on all other lines and is removed from these lines. + +Strings may also contain [interpolations](../../expressions/interpolation). + + + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +// 21-bit unicode characters +a: "\U0001F60E" // 😎 + +// multiline strings +b: """ + Hello + World! + """ +{{< /code-tab >}} +{{< code-tab name="JSON" language="json" type="terminal" area="top-right" >}} +{ + "a": "😎", + "b": "Hello\nWorld!" +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/stringraw/index.md b/hugo/content/en/docs/tour/types/stringraw/index.md new file mode 100644 index 0000000000..d0a624b757 --- /dev/null +++ b/hugo/content/en/docs/tour/types/stringraw/index.md @@ -0,0 +1,37 @@ +--- +title: "\"Raw\" Strings" +weight: 5 +--- +CUE does not support raw strings in the strictest sense. +Instead it allows modifying the escape delimiter by requiring +an arbitrary number of hash `#` signs after the backslash by +enclosing a string literal in an equal number of hash signs on either end. + +This works for normal and interpolated strings. +Quotes do not have to be escaped in such strings. + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +msg1: #"The sequence "\U0001F604" renders as \#U0001F604."# + +msg2: ##""" + A regular expression can conveniently be written as: + + #"\d{3}"# + + This construct works for bytes, strings and their + multi-line variants. + """## +{{< /code-tab >}} +{{< code-tab name="CUE" language="text" type="terminal" area="top-right" >}} +msg1: "The sequence \"\\U0001F604\" renders as 😄." +msg2: """ + A regular expression can conveniently be written as: + + #"\\d{3}"# + + This construct works for bytes, strings and their + multi-line variants. + """ +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/sumstruct/index.md b/hugo/content/en/docs/tour/types/sumstruct/index.md new file mode 100644 index 0000000000..578290946c --- /dev/null +++ b/hugo/content/en/docs/tour/types/sumstruct/index.md @@ -0,0 +1,26 @@ +--- +title: "Disjunctions of Structs" +weight: 12 +--- +Disjunctions work for any type. + +In this example we see that a `floor` of some specific house +has an exit on level 0 and 1, but not on any other floor. + + +```text +// floor defines the specs of a floor in some house. +floor: { + level: int // the level on which this floor resides + hasExit: bool // is there a door to exit the house? +} + +// constraints on the possible values of floor. +floor: { + level: 0 | 1 + hasExit: true +} | { + level: -1 | 2 | 3 + hasExit: false +} +``` diff --git a/hugo/content/en/docs/tour/types/templates/index.md b/hugo/content/en/docs/tour/types/templates/index.md new file mode 100644 index 0000000000..8fdb9a5166 --- /dev/null +++ b/hugo/content/en/docs/tour/types/templates/index.md @@ -0,0 +1,50 @@ +--- +title: "Templates" +weight: 16 +--- +One of CUE's most powerful features is the ability +to specify optional fields in bulk. +This allows one to specify constraints, +or templates, +to be unified with each field of a struct. + +An optional field set is an expression in square brackets +to specify to which fields to apply a constraint +(currently only `string`, or all fields is supported). +Using an alias in the square brackets binds the +label of the matched field to the given identifier, +which can then be used within the template. + + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +// The following struct is unified with all elements in job. +// The name of each element is bound to Name and visible in the struct. +job: [Name=_]: { + name: Name + replicas: uint | *1 + command: string +} + +job: list: command: "ls" + +job: nginx: { + command: "nginx" + replicas: 2 +} +{{< /code-tab >}} +{{< code-tab name="CUE" language="text" type="terminal" area="top-right" >}} +job: { + list: { + name: "list" + replicas: 1 + command: "ls" + } + nginx: { + name: "nginx" + command: "nginx" + replicas: 2 + } +} +{{< /code-tab >}} +{{< /code-tabs >}} diff --git a/hugo/content/en/docs/tour/types/types/index.md b/hugo/content/en/docs/tour/types/types/index.md new file mode 100644 index 0000000000..6227fcee76 --- /dev/null +++ b/hugo/content/en/docs/tour/types/types/index.md @@ -0,0 +1,70 @@ +--- +title: "Type Hierarchy" +weight: 1 +--- +CUE defines the following type hierarchy + +```txt + null bool string bytes number struct list + / \ + int float +``` + +In addition, CUE defines the values +bottom, or error, (denoted `_|_`) +that is an instance of all types and +top, or any, (denoted `_`) of which all types are an instance. + +Note how we use the terms types and values interchangeably. +CUE does not distinguish between types and values. +The term "type" merely refers to the kind of a value, +which may or may not be a concrete instance. + +In the example, `point` defines an arbitrary point, while `xaxis` and `yaxis` +define the points on the respective lines. +We say that `point`, `xaxis`, and `yaxis` are incomplete, +as they do not specify a specific point. +Incomplete values cannot be represented as JSON, +as it can only represent concrete values. + +The only concrete point is `origin`. +The `origin` is defined to be both on the x-axis and y-axis, which means it +must be at `0, 0`. +Here we see constraints in action: +`origin` evalutes to `0, 0`, even though we did not specify its coordinates +explicitly. + +{{< code-tabs >}} +{{< code-tab name="CUE" language="text" area="top-left" >}} +point: { + x: number + y: number +} + +xaxis: point +xaxis: y: 0 + +yaxis: point +yaxis: x: 0 + +origin: xaxis & yaxis +{{< /code-tab >}} +{{< code-tab name="CUE" language="text" type="terminal" area="top-right" >}} +point: { + x: number + y: number +} +xaxis: { + x: number + y: 0 +} +yaxis: { + x: 0 + y: number +} +origin: { + x: 0 + y: 0 +} +{{< /code-tab >}} +{{< /code-tabs >}}