Skip to content

Commit

Permalink
docs/howto: write a type switch
Browse files Browse the repository at this point in the history
This adds a Commented CUE guide demonstrating a type switch.

Closes cue-lang/docs-and-content#14.

Preview-Path: /docs/howto/write-a-type-switch/
Signed-off-by: Jonathan Matthews <[email protected]>
Change-Id: Id70fe2d3a78723d4ef554db28c02aa13decd7793
  • Loading branch information
jpluscplusm committed Feb 13, 2024
1 parent c23543d commit ef27a2d
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 0 deletions.
101 changes: 101 additions & 0 deletions content/docs/howto/write-a-type-switch/en.md
Original file line number Diff line number Diff line change
@@ -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 >}}
18 changes: 18 additions & 0 deletions content/docs/howto/write-a-type-switch/gen_cache.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package site
{
content: {
docs: {
howto: {
"write-a-type-switch": {
page: {
cache: {
code: {
cc: "iFsRYCFDaDhgW1KEJuaeEi8Y9vc5tdmhJZnul/THg/Y="
}
}
}
}
}
}
}
}
3 changes: 3 additions & 0 deletions content/docs/howto/write-a-type-switch/page.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package site

content: docs: howto: "write-a-type-switch": {}
100 changes: 100 additions & 0 deletions hugo/content/en/docs/howto/write-a-type-switch/index.md
Original file line number Diff line number Diff line change
@@ -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 >}}

0 comments on commit ef27a2d

Please sign in to comment.