From 63169394381bb8c7e7e0e9f8f134a69ccef15009 Mon Sep 17 00:00:00 2001 From: Hare Date: Tue, 16 Jun 2026 10:04:44 +0900 Subject: [PATCH] Add advanced Decodal example --- examples/advanced/README.md | 22 +++++++++++++++ examples/advanced/main.dcdl | 47 +++++++++++++++++++++++++++++++++ examples/advanced/profiles.dcdl | 18 +++++++++++++ examples/advanced/schema.dcdl | 17 ++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 examples/advanced/README.md create mode 100644 examples/advanced/main.dcdl create mode 100644 examples/advanced/profiles.dcdl create mode 100644 examples/advanced/schema.dcdl diff --git a/examples/advanced/README.md b/examples/advanced/README.md new file mode 100644 index 0000000..3b51fae --- /dev/null +++ b/examples/advanced/README.md @@ -0,0 +1,22 @@ +# Advanced Decodal example + +This example exercises multiple current Decodal features together: + +- multi-file `import` +- top-level recursive module scope +- schema/value composition with `&` +- deep patch with `//` +- `default` fallback during materialization +- constrained function parameters +- lazy function arguments +- `match` expressions +- nested dot-path fields +- arrays + +Run it with: + +```sh +cargo run -q -p decodal -- examples/advanced/main.dcdl +``` + +The entrypoint is `main.dcdl`. diff --git a/examples/advanced/main.dcdl b/examples/advanced/main.dcdl new file mode 100644 index 0000000..0df7cc4 --- /dev/null +++ b/examples/advanced/main.dcdl @@ -0,0 +1,47 @@ +let + schema = import "./schema.dcdl"; + profiles = import "./profiles.dcdl"; + + mkService = (cfg: schema.Service) => + cfg // { + summary = match cfg.env { + "prod": "production service"; + "dev": "development service"; + _: "custom service"; + }; + }; + + devService = mkService( + profiles.base & { + name = "api-dev"; + port = 8443; + } + ); + + prodService = mkService( + profiles.prod & { + name = "api"; + port = 9443; + } + ); + + disabledService = mkService( + profiles.disabled & { + name = "api-disabled"; + port = 10443; + } + ); +in +{ + services = [ + devService, + prodService, + disabledService, + ]; + + selected = match "prod" { + "prod": prodService; + "dev": devService; + _: disabledService; + }; +} diff --git a/examples/advanced/profiles.dcdl b/examples/advanced/profiles.dcdl new file mode 100644 index 0000000..d011f18 --- /dev/null +++ b/examples/advanced/profiles.dcdl @@ -0,0 +1,18 @@ +# Environment-specific patches. + +base = { + env = "dev"; + tags = ["decodal", "dev"]; +}; + +prod = base // { + env = "prod"; + host = "api.internal"; + feature.limit = 100; + tags = ["decodal", "prod"]; +}; + +disabled = base // { + feature.enable = false; + tags = ["decodal", "disabled"]; +}; diff --git a/examples/advanced/schema.dcdl b/examples/advanced/schema.dcdl new file mode 100644 index 0000000..9b51dc8 --- /dev/null +++ b/examples/advanced/schema.dcdl @@ -0,0 +1,17 @@ +# Shared service schema. +# Top-level fields are recursive, so SecurePort can refer to Port. + +Port = Int & >= 1 & <= 65535; +SecurePort = Port & > 443; + +Service = { + name = String; + env = String default "dev"; + host = String default "localhost"; + port = SecurePort default 8443; + + feature = { + enable = Bool default true; + limit = Int & >= 0 default 10; + }; +};