23 ccl standard library
The ccl module implements the Categorical Configuration Language (CCL) parser, data model, deterministic serializer, and #! compile-time structural encoder/decoder.
#use ccl23.1 Data model
The core document model represents nested, indentation-delimited key-value entries:
#type Strings String{}
#type CclVal <
Str(String),
Block(CclDoc)
>
#type CclEntry (
key: String,
val: CclVal,
line: Int,
col: Int
)
#type CclEntries CclEntry{}
#type CclDoc CclEntry{}23.2 Structural encoding and decoding (#!)
ccl provides compile-time structural codecs for records, tuples, enums, options, arrays, maps, primitives, and CclDoc:
| Function | Signature | Description |
|---|---|---|
ccl::encode |
val => String |
Serialize any record, map, or CclDoc into a canonical CCL string |
ccl::decode |
#! T, String => < T | Error > |
Parse CCL text and decode into target type T |
ccl::decode_file |
#! T, String => < T | Error > |
Read a file from disk and decode its CCL contents into T |
ccl::to_doc |
val => CclDoc |
Convert any record, map, or CclDoc into a CclDoc |
ccl::to_ccl_val |
val => CclVal |
Convert any value into a CclVal |
ccl::decode_doc |
#! T, CclDoc => < T | Error > |
Decode a parsed CclDoc into target type T |
ccl::decode_val |
#! T, CclVal => < T | Error > |
Decode a CclVal into target type T |
23.2.1 Codec conventions
- Forward-compatible records (
[(..)]): Unknown keys in input are ignored. Missing keys use declared field defaults (f.default),<-->for option fields (<P|>), orf.type.zerofor emptyable containers (E{},K ^ V); anErroris returned only when a required non-option field with no default is missing. - External enum tagging (
[<..>]): Unit variants encode and decode as plain strings ("VariantName"), while payload variants encode and decode as single-entry blocks (VariantName = payload). - Boolean flags (
[<>]):ccl::to_ccl_val/ccl::encodeserializes<+>as"true"and<->as"false". Inccl::decode_val, a string entry (Str s) decodes to<+>(true) whensis"true","1", or"yes", and decodes to<->(false) whensis"false","0", or"no"; any other string or a block entry returns anError.
#type ServerCfg (
host: String = "127.0.0.1",
port: Int = 8080,
tls: <> = <->,
cert_path: < String | >,
tags: String{}
)
text = ccl::encode(ServerCfg("0.0.0.0", 9090, <+>, <+ "/etc/ssl/cert.pem" +>, String{}("api", "prod")))
cfg = ccl::decode(ServerCfg, text)!!23.3 Document parsing and query helpers
| Function | Signature | Description |
|---|---|---|
ccl::parse |
String, String => < CclDoc | Error > |
Parse CCL text with an associated source path for diagnostics |
ccl::parse_file |
String => < CclDoc | Error > |
Read and parse a CCL configuration file from disk |
ccl::to_ccl |
CclDoc => String |
Serialize a CclDoc into a canonical, deterministic CCL string |
ccl::has |
CclDoc, String => <> |
Check if a top-level key exists in the document |
ccl::get |
CclDoc, String => < String | > |
Retrieve the string value of a top-level key |
ccl::get_section |
CclDoc, String => < CclDoc | > |
Retrieve a nested block section as a sub-document |
ccl::get_list |
CclDoc, String => < Strings | > |
Retrieve = item list entries inside the named section |
ccl::entries_for |
CclDoc, String => Strings |
Retrieve all string values for repeated occurrences of a key |
doc = ccl::parse("name = demo\nversion = 0.1.0", "edva.ccl")!!
name = ccl::get(doc, "name") | n => n | "unknown"