diff --git a/content/docs/howto/write-a-type-switch/en.md b/content/docs/howto/write-a-type-switch/en.md new file mode 100644 index 0000000000..b1eae1a0a9 --- /dev/null +++ b/content/docs/howto/write-a-type-switch/en.md @@ -0,0 +1,101 @@ +--- +title: Writing a type switch +tags: +- commented cue +authors: +- jpluscplusm +toc_hide: true +--- + +This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}}) +demonstrates how to write a **type switch**, where output needs to differ based +on the type of data being processed. Because the CUE language does not include +a switch statement, a mechanism is shown that *behaves* like a switch statement +in some other languages. + +{{{with code "en" "cc"}}} +#location top bottom + +exec cue eval -s -e output +cmp stdout out +-- file.cue -- +package example + +input: [ + 42, + 139.4, + "some string", + ["some", "list"], + {some: "struct"}, + true, + false, +] + +// output is derived from input, and adheres to the following schema: +output: [...{ + source!: _ // the value being examined + type!: string // source's type, in words + isANumber!: bool // true iff source is a number +}] + +output: [for v in input { + source: v + + // type's trailing "[0]" acts like a switch statement, selecting the + // first value whose conditional evaluates to true. + type: [ + if (v & string) != _|_ {"a string"}, + if (v & int) != _|_ {"an int"}, + if (v & float) != _|_ {"a float"}, + if (v & bool) != _|_ {"a boolean"}, + if (v & [...]) != _|_ {"a list"}, + if (v & {...}) != _|_ {"a struct"}, + ][0] + + // Here, isANumber is implemented as a switch. Other, simpler, + // representations are also possible. + isANumber: [ + if (v & number) != _|_ {true}, + if (v & number) == _|_ {false}, + ][0] +}] +-- out -- +[{ + source: 42 + type: "an int" + isANumber: true +}, { + source: 139.4 + type: "a float" + isANumber: true +}, { + source: "some string" + type: "a string" + isANumber: false +}, { + source: ["some", "list"] + type: "a list" + isANumber: false +}, { + source: some: "struct" + type: "a struct" + isANumber: false +}, { + source: true + type: "a boolean" + isANumber: false +}, { + source: false + type: "a boolean" + isANumber: false +}] +{{{end}}} + +{{< info >}} +The method of testing a value's type shown in this guide is likely to be +replaced by tests using more specific and precise builtins when +{{< issue 943 />}} is implemented, such as `isconcrete`. + +The builtins mentioned in that issue **are not yet available**, but we mention +them here to help guide the implementation choices you make in the interim. +{{< /info >}} diff --git a/content/docs/howto/write-a-type-switch/gen_cache.cue b/content/docs/howto/write-a-type-switch/gen_cache.cue new file mode 100644 index 0000000000..d3d9527dc3 --- /dev/null +++ b/content/docs/howto/write-a-type-switch/gen_cache.cue @@ -0,0 +1,18 @@ +package site +{ + content: { + docs: { + howto: { + "write-a-type-switch": { + page: { + cache: { + code: { + cc: "iFsRYCFDaDhgW1KEJuaeEi8Y9vc5tdmhJZnul/THg/Y=" + } + } + } + } + } + } + } +} diff --git a/content/docs/howto/write-a-type-switch/page.cue b/content/docs/howto/write-a-type-switch/page.cue new file mode 100644 index 0000000000..7c46797458 --- /dev/null +++ b/content/docs/howto/write-a-type-switch/page.cue @@ -0,0 +1,3 @@ +package site + +content: docs: howto: "write-a-type-switch": {} diff --git a/hugo/content/en/docs/howto/write-a-type-switch/index.md b/hugo/content/en/docs/howto/write-a-type-switch/index.md new file mode 100644 index 0000000000..2f949bb6b7 --- /dev/null +++ b/hugo/content/en/docs/howto/write-a-type-switch/index.md @@ -0,0 +1,100 @@ +--- +title: Writing a type switch +tags: +- commented cue +authors: +- jpluscplusm +toc_hide: true +--- + +This [Commented CUE]({{< relref "docs/howto#commented-cue-guides" >}}) +demonstrates how to write a **type switch**, where output needs to differ based +on the type of data being processed. Because the CUE language does not include +a switch statement, a mechanism is shown that *behaves* like a switch statement +in some other languages. + +{{< code-tabs >}} +{{< code-tab name="file.cue" language="cue" area="top" >}} +package example + +input: [ + 42, + 139.4, + "some string", + ["some", "list"], + {some: "struct"}, + true, + false, +] + +// output is derived from input, and adheres to the following schema: +output: [...{ + source!: _ // the value being examined + type!: string // source's type, in words + isANumber!: bool // true iff source is a number +}] + +output: [for v in input { + source: v + + // type's trailing "[0]" acts like a switch statement, selecting the + // first value whose conditional evaluates to true. + type: [ + if (v & string) != _|_ {"a string"}, + if (v & int) != _|_ {"an int"}, + if (v & float) != _|_ {"a float"}, + if (v & bool) != _|_ {"a boolean"}, + if (v & [...]) != _|_ {"a list"}, + if (v & {...}) != _|_ {"a struct"}, + ][0] + + // Here, isANumber is implemented as a switch. Other, simpler, + // representations are also possible. + isANumber: [ + if (v & number) != _|_ {true}, + if (v & number) == _|_ {false}, + ][0] +}] +{{< /code-tab >}} +{{< code-tab name="TERMINAL" language="" type="terminal" area="bottom" >}} +$ cue eval -s -e output +[{ + source: 42 + type: "an int" + isANumber: true +}, { + source: 139.4 + type: "a float" + isANumber: true +}, { + source: "some string" + type: "a string" + isANumber: false +}, { + source: ["some", "list"] + type: "a list" + isANumber: false +}, { + source: some: "struct" + type: "a struct" + isANumber: false +}, { + source: true + type: "a boolean" + isANumber: false +}, { + source: false + type: "a boolean" + isANumber: false +}] +{{< /code-tab >}} +{{< /code-tabs >}} + +{{< info >}} +The method of testing a value's type shown in this guide is likely to be +replaced by tests using more specific and precise builtins when +{{< issue 943 />}} is implemented, such as `isconcrete`. + +The builtins mentioned in that issue **are not yet available**, but we mention +them here to help guide the implementation choices you make in the interim. +{{< /info >}}