File-driven Config
Load a YAML config file at compile time, validate it against a typed schema, and reshape it into a deployment manifest.
Source
examples/file-driven-config/input.yaml
services:
- name: api
port: 8080
enabled: true
- name: worker
port: 9090
enabled: true
- name: admin
port: 7070
enabled: false
database:
host: db.internal
port: 5432
name: app
examples/file-driven-config/main.rank
/// Reads a YAML config file at compile time and reshapes it into a
/// deployment manifest. Shows File::Read with a typed schema and
/// stdlib transforms on the loaded data.
use std::File
use std::Path
use std::collections::{ filter, map }
use std::Emit
ServiceEntry = Object {
name: string,
port: number,
enabled: bool,
}
InputConfig = Object {
services: [ServiceEntry],
database: Object {
host: string,
port: number,
name: string,
},
}
DeployedService = Object {
name: string,
port: number,
address: string,
}
response = File::Read<InputConfig> {
path: Path::join([`input.yaml`]),
format: `yaml`,
}
input = response.body
active_services: [DeployedService] = input.services
|> filter(|svc: ServiceEntry| svc.enabled)
|> map(|svc: ServiceEntry| -> DeployedService {
return {
name: svc.name,
port: svc.port,
address: `${svc.name}.internal:${svc.port}`,
}
})
manifest = {
services: active_services,
database: input.database,
}
pub main = || Emit::manifest({
entries: [
{
path: Path::join([`manifest.json`]),
format: `json`,
value: manifest,
},
{
path: Path::join([`manifest.yaml`]),
format: `yaml`,
value: manifest,
},
]
})
Output
// manifest.json
{
"services": [
{ "name": "api", "port": 8080, "address": "api.internal:8080" },
{ "name": "worker", "port": 9090, "address": "worker.internal:9090" }
],
"database": {
"host": "db.internal",
"port": 5432,
"name": "app"
}
}
The admin service is excluded because enabled: false.
The same manifest is also emitted as manifest.yaml.
Key concepts
File::Read<T>— reads and parses a file into the typed schemaT. A schema mismatch is a compile-time error.response.body— the parsed, type-checked content of the file.response.ctx— metadata:{ path, format }.Path::join— constructs aPath::RelativePathfrom path segments. Paths are resolved relative to the project source root.Emit::manifest(...)— emits both JSON and YAML artifacts from the same typed manifest descriptor.- Filter then map — the pipe chain keeps only enabled services and builds the
addressfield, leaving the database block untouched.
Run it
rank examples/file-driven-config