Add bilingual manual and localized docs routes
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
# Examples
|
||||
|
||||
This chapter combines Decodal's main constructs in complete examples.
|
||||
|
||||
## Basic configuration schema
|
||||
|
||||
```dcdl
|
||||
Host = String;
|
||||
|
||||
Port = Int & >= 1 & <= 65535;
|
||||
NarrowedPort = Port & > 443;
|
||||
|
||||
MyConfig = {
|
||||
host = Host;
|
||||
port = NarrowedPort default 8080;
|
||||
feature_hoge = {
|
||||
enable = Bool default true;
|
||||
fuga = Int default 10;
|
||||
};
|
||||
};
|
||||
|
||||
NewConfig = MyConfig & {
|
||||
host = "127.0.0.1";
|
||||
port = 8000;
|
||||
};
|
||||
|
||||
disabled_config = NewConfig & {
|
||||
feature_hoge.enable = false;
|
||||
};
|
||||
|
||||
enabled_config = NewConfig;
|
||||
```
|
||||
|
||||
## Array schema
|
||||
|
||||
```dcdl
|
||||
Services = [...{
|
||||
name = String;
|
||||
port = Int default 8080;
|
||||
}];
|
||||
|
||||
[
|
||||
{ name = "api"; },
|
||||
{ name = "worker"; port = 9000; },
|
||||
] as Services
|
||||
```
|
||||
|
||||
An abstract array requires an element constraint.
|
||||
In this example, `port` in the first element materializes to `8080`.
|
||||
|
||||
## Associative arrays and range refinement
|
||||
|
||||
```dcdl
|
||||
Service = {
|
||||
port = Int;
|
||||
enabled = Bool default true;
|
||||
};
|
||||
|
||||
services = {
|
||||
api = { port = 8080; };
|
||||
worker = { port = 8081; enabled = false; };
|
||||
} as {...Service};
|
||||
```
|
||||
|
||||
`api` and `worker` are arbitrary keys, and each value is refined to a range narrower than `Service`.
|
||||
In the result of `as`, `api.enabled` remains abstract. Its default of `true` is selected only when the complete result is materialized.
|
||||
|
||||
## Functions and constraints
|
||||
|
||||
```dcdl
|
||||
let
|
||||
Port = Int & >= 1 & <= 65535;
|
||||
add_offset = (base: Port, offset: Int) => base + offset;
|
||||
in
|
||||
add_offset(8000, 80)
|
||||
```
|
||||
|
||||
Evaluation result:
|
||||
|
||||
```text
|
||||
8080
|
||||
```
|
||||
|
||||
## match
|
||||
|
||||
```dcdl
|
||||
(
|
||||
input_a: {
|
||||
hoge = Int & >= 0;
|
||||
},
|
||||
input_b: {
|
||||
fuga = 20;
|
||||
}
|
||||
) =>
|
||||
let
|
||||
inputs = {
|
||||
a = input_a;
|
||||
b = input_b;
|
||||
};
|
||||
in
|
||||
{
|
||||
foo = match inputs.a.hoge {
|
||||
>= 20: {
|
||||
value = 200;
|
||||
};
|
||||
>= 10: {
|
||||
value = 100;
|
||||
};
|
||||
_: {
|
||||
value = 300;
|
||||
};
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
`match` evaluates arms in order, so place narrower conditions before broader ones.
|
||||
|
||||
## Deep patch
|
||||
|
||||
```dcdl
|
||||
Base = {
|
||||
feature_hoge = {
|
||||
enable = Bool default true;
|
||||
fuga = Int default 10;
|
||||
};
|
||||
};
|
||||
|
||||
Patched = Base // {
|
||||
feature_hoge.enable = false;
|
||||
};
|
||||
```
|
||||
|
||||
`Patched` is equivalent to:
|
||||
|
||||
```dcdl
|
||||
{
|
||||
feature_hoge = {
|
||||
enable = false;
|
||||
fuga = Int default 10;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Cyclic imports
|
||||
|
||||
```dcdl
|
||||
# main.dcdl
|
||||
{
|
||||
schema = {
|
||||
hoge = String;
|
||||
};
|
||||
|
||||
result = (import "./func.dcdl")(schema);
|
||||
}
|
||||
```
|
||||
|
||||
```dcdl
|
||||
# func.dcdl
|
||||
(input: (import "./main.dcdl").schema) =>
|
||||
{
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
`func.dcdl` imports `main.dcdl`, but it references only `main.schema`.
|
||||
The cyclic import is valid as long as `main.schema` does not depend on `main.result`.
|
||||
Reference in New Issue
Block a user