167 lines
2.8 KiB
Markdown
167 lines
2.8 KiB
Markdown
# 例
|
|
|
|
この章では、Decodal の主要な記法を組み合わせた例を示す。
|
|
|
|
## 基本的な設定スキーマ
|
|
|
|
```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;
|
|
```
|
|
|
|
## 配列スキーマ
|
|
|
|
```dcdl
|
|
Services = [...{
|
|
name = String;
|
|
port = Int default 8080;
|
|
}];
|
|
|
|
[
|
|
{ name = "api"; },
|
|
{ name = "worker"; port = 9000; },
|
|
] as Services
|
|
```
|
|
|
|
抽象配列には要素制約が必須である。
|
|
この例では、1 番目の要素の `port` は `8080` に materialize される。
|
|
|
|
## 連想配列と範囲絞り込み
|
|
|
|
```dcdl
|
|
Service = {
|
|
port = Int;
|
|
enabled = Bool default true;
|
|
};
|
|
|
|
services = {
|
|
api = { port = 8080; };
|
|
worker = { port = 8081; enabled = false; };
|
|
} as {...Service};
|
|
```
|
|
|
|
`api` と `worker` は任意の key であり、それぞれの value は `Service` より狭い範囲へ絞り込まれる。
|
|
`as` の結果では `api.enabled` は abstract のまま残り、最終的に結果全体を materialize した時点で default の `true` が使われる。
|
|
|
|
## 関数と制約
|
|
|
|
```dcdl
|
|
let
|
|
Port = Int & >= 1 & <= 65535;
|
|
add_offset = (base: Port, offset: Int) => base + offset;
|
|
in
|
|
add_offset(8000, 80)
|
|
```
|
|
|
|
評価結果:
|
|
|
|
```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` は上から順に評価されるため、広い条件より狭い条件を先に書く。
|
|
|
|
## deep patch
|
|
|
|
```dcdl
|
|
Base = {
|
|
feature_hoge = {
|
|
enable = Bool default true;
|
|
fuga = Int default 10;
|
|
};
|
|
};
|
|
|
|
Patched = Base // {
|
|
feature_hoge.enable = false;
|
|
};
|
|
```
|
|
|
|
`Patched` は以下に相当する。
|
|
|
|
```dcdl
|
|
{
|
|
feature_hoge = {
|
|
enable = false;
|
|
fuga = Int default 10;
|
|
};
|
|
}
|
|
```
|
|
|
|
## 循環 import
|
|
|
|
```dcdl
|
|
# main.dcdl
|
|
{
|
|
schema = {
|
|
hoge = String;
|
|
};
|
|
|
|
result = (import "./func.dcdl")(schema);
|
|
}
|
|
```
|
|
|
|
```dcdl
|
|
# func.dcdl
|
|
(input: (import "./main.dcdl").schema) =>
|
|
{
|
|
# ...
|
|
}
|
|
```
|
|
|
|
`func.dcdl` は `main.dcdl` を import しているが、参照しているのは `main.schema` である。
|
|
`main.schema` が `main.result` に依存していなければ、この循環 import は成立する。
|