Skip to main content

bynk_syntax/
keywords.rs

1//! Registry of reserved keywords.
2//!
3//! Single source of truth for the keyword list in
4//! `docs/src/reference/keywords.md`, generated by [`render_markdown`]. The test
5//! `tests/keywords_reference.rs` asserts this table matches exactly the
6//! alphabetic `#[token("…")]` keywords declared in `lexer.rs`, so the two
7//! cannot drift.
8
9/// One reserved keyword and a one-line description of its role.
10pub struct KeywordInfo {
11    pub word: &'static str,
12    pub meaning: &'static str,
13}
14
15/// Every reserved keyword, sorted.
16pub const KEYWORDS: &[KeywordInfo] = &[
17    k("Bool", "The boolean base type."),
18    k("Effect", "The effectful-computation type, `Effect[T]`."),
19    k("Err", "The error variant of `Result`."),
20    k("Float", "The floating-point base type."),
21    k("Int", "The integer base type."),
22    k(
23        "JsonError",
24        "The JSON-decode error type, `Result[T, JsonError]` from `Json.decode`.",
25    ),
26    k("None", "The empty variant of `Option`."),
27    k("Ok", "The success variant of `Result`."),
28    k("Option", "The optional-value type, `Option[T]`."),
29    k("Result", "The success-or-error type, `Result[T, E]`."),
30    k("Some", "The present variant of `Option`."),
31    k("String", "The string base type."),
32    k(
33        "ValidationError",
34        "The error type returned by a refined type's `.of`.",
35    ),
36    k(
37        "actor",
38        "Declare an actor — a boundary contract a handler consumes via `by`.",
39    ),
40    k(
41        "adapter",
42        "Declare an adapter — the host boundary (capability contract + binding).",
43    ),
44    k("agent", "Declare a stateful, keyed agent inside a context."),
45    k("and", "Combine refinement predicates (`where A and B`)."),
46    k("as", "Alias a consumed context (`consumes X as Y`)."),
47    k("assert", "Assert a condition inside a test case."),
48    k(
49        "binding",
50        "Name an adapter's TypeScript binding module (`binding \"<module>\"`).",
51    ),
52    k(
53        "by",
54        "Name the actor a handler consumes (`on … by <name>: <Actor>`).",
55    ),
56    k(
57        "capability",
58        "Declare a capability (a dependency interface) in a context.",
59    ),
60    k("commit", "Persist new agent state from within a handler."),
61    k(
62        "commons",
63        "Declare a pure, stateless module of types and functions.",
64    ),
65    k(
66        "consumes",
67        "Declare a dependency on another context's services.",
68    ),
69    k(
70        "context",
71        "Declare a deployable context (services, agents, capabilities).",
72    ),
73    k(
74        "cron",
75        "The cron protocol on a service header (`from cron`).",
76    ),
77    k("else", "The alternative branch of an `if` expression."),
78    k("enum", "Declare a payloadless sum type (`enum { A, B }`)."),
79    k("expect", "Reserved keyword."),
80    k("exports", "Declare which types a context exposes, and how."),
81    k("false", "The boolean literal `false`."),
82    k("fn", "Declare a function."),
83    k(
84        "from",
85        "Name the protocol a service conforms to (`service X from http`).",
86    ),
87    k("given", "Declare the capabilities a handler requires."),
88    k(
89        "http",
90        "The HTTP protocol on a service header (`from http`).",
91    ),
92    k("if", "A conditional expression."),
93    k(
94        "is",
95        "Test a value against a variant pattern, yielding a `Bool`.",
96    ),
97    k(
98        "let",
99        "Bind a local value (`let x = …`, or `let x <- …` for an effect).",
100    ),
101    k(
102        "match",
103        "Pattern-match over a sum type, `Result`, or `Option`.",
104    ),
105    k(
106        "mocks",
107        "Provide a mock capability implementation in a test.",
108    ),
109    k(
110        "on",
111        "Begin a handler declaration (`on call`, `on GET(…)`, `on message`).",
112    ),
113    k(
114        "opaque",
115        "Declare an opaque type, or export a type opaquely.",
116    ),
117    k(
118        "protocol",
119        "Reserved keyword (protocols are a closed, compiler-known set).",
120    ),
121    k("provides", "Provide an implementation of a capability."),
122    k(
123        "queue",
124        "The queue protocol on a service header (`from queue(\"name\")`).",
125    ),
126    k(
127        "record",
128        "Reserved keyword (records are written `type X = { … }`).",
129    ),
130    k("self", "The current agent instance, inside a handler."),
131    k(
132        "service",
133        "Declare a service (a group of handlers) in a context.",
134    ),
135    k("state", "Declare an agent's persistent state block."),
136    k("test", "Declare a test block or a test case."),
137    k(
138        "transparent",
139        "Export a type with its structure visible (`exports transparent { … }`).",
140    ),
141    k("true", "The boolean literal `true`."),
142    k(
143        "type",
144        "Declare a type: alias, record, sum, opaque, or refined.",
145    ),
146    k("uses", "Bring a commons into scope."),
147    k("where", "Attach refinement predicates to a base type."),
148    k(
149        "wires",
150        "List the contexts a `test integration` stands up as Workers.",
151    ),
152];
153
154const fn k(word: &'static str, meaning: &'static str) -> KeywordInfo {
155    KeywordInfo { word, meaning }
156}
157
158/// Render the keyword list as a Markdown reference page.
159pub fn render_markdown() -> String {
160    let mut out = String::new();
161    out.push_str("# Keywords\n\n");
162    out.push_str(
163        "<!-- GENERATED FILE — do not edit by hand.\n     \
164         Source: bynkc/src/keywords.rs (`render_markdown`).\n     \
165         Regenerate with: BYNK_BLESS=1 cargo test -p bynkc --test keywords_reference -->\n\n",
166    );
167    out.push_str(
168        "Every reserved keyword, with a one-line description. Reserved words cannot \
169         be used as identifiers.\n\n",
170    );
171    out.push_str(&format!(
172        "There are **{}** reserved keywords.\n\n",
173        KEYWORDS.len()
174    ));
175    out.push_str("| Keyword | Meaning |\n|---|---|\n");
176    for info in KEYWORDS {
177        out.push_str(&format!("| `{}` | {} |\n", info.word, info.meaning));
178    }
179    out
180}