2.6 KiB
2.6 KiB
Examples
This chapter combines Decodal's main constructs in complete examples.
Basic configuration schema
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
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
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
let
Port = Int & >= 1 & <= 65535;
add_offset = (base: Port, offset: Int) => base + offset;
in
add_offset(8000, 80)
Evaluation result:
8080
match
(
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
Base = {
feature_hoge = {
enable = Bool default true;
fuga = Int default 10;
};
};
Patched = Base // {
feature_hoge.enable = false;
};
Patched is equivalent to:
{
feature_hoge = {
enable = false;
fuga = Int default 10;
};
}
Cyclic imports
# main.dcdl
{
schema = {
hoge = String;
};
result = (import "./func.dcdl")(schema);
}
# 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.