@macroforge/mcp-server 0.1.65 → 0.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/tools/docs-loader.d.ts.map +1 -1
- package/dist/tools/docs-loader.js +1 -1
- package/dist/tools/docs-loader.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +84 -85
- package/dist/tools/index.js.map +1 -1
- package/docs/BOOK.md +8 -33
- package/docs/api/api-overview.md +4 -4
- package/docs/api/expand-sync.md +3 -2
- package/docs/api/native-plugin.md +5 -2
- package/docs/api/position-mapper.md +7 -4
- package/docs/api/transform-sync.md +7 -5
- package/docs/builtin-macros/deserialize/all-options.md +7 -21
- package/docs/builtin-macros/deserialize/combining-with-serialize.md +7 -5
- package/docs/builtin-macros/deserialize/enum-support.md +8 -6
- package/docs/builtin-macros/deserialize/error-handling.md +10 -9
- package/docs/builtin-macros/deserialize/interface-support.md +9 -4
- package/docs/builtin-macros/deserialize/runtime-validation.md +10 -21
- package/docs/builtin-macros/deserialize/serde-options.md +19 -31
- package/docs/builtin-macros/deserialize/type-alias-support.md +7 -6
- package/docs/builtin-macros/macros-overview/detailed-documentation.md +9 -9
- package/docs/builtin-macros/macros-overview/enum-support.md +3 -2
- package/docs/builtin-macros/macros-overview/interface-support.md +3 -2
- package/docs/builtin-macros/macros-overview/overview.md +13 -12
- package/docs/builtin-macros/macros-overview/type-alias-support.md +3 -2
- package/docs/builtin-macros/macros-overview.md +27 -23
- package/docs/builtin-macros/partial-eq/example.md +188 -232
- package/docs/builtin-macros/partial-eq/overview.md +18 -18
- package/docs/builtin-macros/serialize/example.md +11 -3
- package/docs/builtin-macros/serialize/overview.md +12 -11
- package/docs/builtin-macros/serialize/type-specific-serialization.md +12 -12
- package/docs/concepts/architecture.md +23 -22
- package/docs/concepts/derive-system/built-in-vs-custom-macros.md +4 -3
- package/docs/concepts/derive-system/overview.md +27 -24
- package/docs/concepts/derive-system.md +31 -27
- package/docs/concepts/how-macros-work.md +23 -21
- package/docs/custom-macros/custom-overview.md +9 -8
- package/docs/custom-macros/rust-setup.md +11 -10
- package/docs/custom-macros/ts-macro-derive/accessing-field-data.md +2 -1
- package/docs/custom-macros/ts-macro-derive/adding-imports.md +2 -1
- package/docs/custom-macros/ts-macro-derive/attribute-options.md +1 -1
- package/docs/custom-macros/ts-macro-derive/complete-example.md +1 -1
- package/docs/custom-macros/ts-macro-derive/deriveinput-structure.md +1 -1
- package/docs/custom-macros/ts-macro-derive/function-signature.md +1 -1
- package/docs/custom-macros/ts-macro-derive/overview.md +3 -2
- package/docs/custom-macros/ts-macro-derive/parsing-input.md +1 -1
- package/docs/custom-macros/ts-macro-derive/returning-errors.md +1 -1
- package/docs/custom-macros/ts-macro-derive.md +7 -4
- package/docs/custom-macros/ts-quote/backtick-template-literals.md +5 -3
- package/docs/custom-macros/ts-quote/comments-and.md +3 -2
- package/docs/custom-macros/ts-quote/complete-example-json-derive-macro.md +12 -11
- package/docs/custom-macros/ts-quote/conditionals-ifif.md +1 -1
- package/docs/custom-macros/ts-quote/identifier-concatenation-content.md +5 -3
- package/docs/custom-macros/ts-quote/interpolation-expr.md +18 -11
- package/docs/custom-macros/ts-quote/iteration-for.md +1 -1
- package/docs/custom-macros/ts-quote/local-constants-let.md +1 -1
- package/docs/custom-macros/ts-quote/match-expressions-match.md +1 -1
- package/docs/custom-macros/ts-quote/overview.md +4 -2
- package/docs/custom-macros/ts-quote/pattern-matching-if-let.md +2 -2
- package/docs/custom-macros/ts-quote/pattern-matching-iflet.md +1 -1
- package/docs/custom-macros/ts-quote/quick-reference.md +24 -23
- package/docs/custom-macros/ts-quote/side-effects-do.md +6 -5
- package/docs/custom-macros/ts-quote/string-interpolation-text-expr.md +3 -3
- package/docs/custom-macros/ts-quote/string-interpolation-textexpr.md +1 -1
- package/docs/custom-macros/ts-quote/tsstream-injection-typescript.md +3 -2
- package/docs/custom-macros/ts-quote/while-loops-while.md +1 -1
- package/docs/custom-macros/ts-quote.md +30 -19
- package/docs/getting-started/first-macro.md +5 -4
- package/docs/getting-started/installation.md +20 -17
- package/docs/integration/cli.md +11 -5
- package/docs/integration/configuration.md +7 -9
- package/docs/integration/integration-overview.md +5 -5
- package/docs/integration/mcp-server.md +17 -8
- package/docs/integration/svelte-preprocessor.md +18 -14
- package/docs/integration/typescript-plugin.md +14 -12
- package/docs/integration/vite-plugin.md +13 -11
- package/docs/language-servers/ls-overview.md +18 -12
- package/docs/language-servers/svelte-ls.md +9 -11
- package/docs/language-servers/svelte.md +18 -17
- package/docs/language-servers/zed-extensions.md +14 -11
- package/docs/language-servers/zed.md +19 -13
- package/docs/roadmap/roadmap.md +8 -6
- package/package.json +4 -4
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# Rust Setup
|
|
2
2
|
|
|
3
|
-
Create a new Rust crate that will contain your custom macros. This crate compiles to a native
|
|
3
|
+
Create a new Rust crate that will contain your custom macros. This crate compiles to a native
|
|
4
|
+
Node.js addon.
|
|
4
5
|
|
|
5
6
|
## Prerequisites
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
- Rust toolchain (1.88 or later)
|
|
9
|
+
- Node.js 24 or later
|
|
10
|
+
- NAPI-RS CLI: `cargo install macroforge_ts`
|
|
10
11
|
|
|
11
12
|
## Create the Project
|
|
12
13
|
|
|
@@ -25,7 +26,7 @@ napi new --platform --name my-macros
|
|
|
25
26
|
|
|
26
27
|
Update your `Cargo.toml` with the required dependencies:
|
|
27
28
|
|
|
28
|
-
Cargo.toml
|
|
29
|
+
Cargo.toml
|
|
29
30
|
|
|
30
31
|
```
|
|
31
32
|
[package]
|
|
@@ -51,7 +52,7 @@ strip = true
|
|
|
51
52
|
|
|
52
53
|
## Create build.rs
|
|
53
54
|
|
|
54
|
-
build.rs
|
|
55
|
+
build.rs
|
|
55
56
|
|
|
56
57
|
```
|
|
57
58
|
fn main() {
|
|
@@ -61,7 +62,7 @@ fn main() {
|
|
|
61
62
|
|
|
62
63
|
## Create src/lib.rs
|
|
63
64
|
|
|
64
|
-
src/lib.rs
|
|
65
|
+
src/lib.rs
|
|
65
66
|
|
|
66
67
|
```
|
|
67
68
|
use macroforge_ts::macros::{ts_macro_derive, body};
|
|
@@ -98,7 +99,7 @@ pub fn derive_json(mut input: TsStream) -> Result<TsStream, MacroforgeErr
|
|
|
98
99
|
|
|
99
100
|
## Create package.json
|
|
100
101
|
|
|
101
|
-
package.json
|
|
102
|
+
package.json
|
|
102
103
|
|
|
103
104
|
```
|
|
104
105
|
{
|
|
@@ -147,5 +148,5 @@ For cross-platform builds, use GitHub Actions with the NAPI-RS CI template.
|
|
|
147
148
|
|
|
148
149
|
## Next Steps
|
|
149
150
|
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
- [Learn the #\[ts\_macro\_derive\] attribute](../../docs/custom-macros/ts-macro-derive)
|
|
152
|
+
- [Master the template syntax](../../docs/custom-macros/ts-quote)
|
|
@@ -59,4 +59,5 @@ struct DecoratorIR {
|
|
|
59
59
|
|
|
60
60
|
Note
|
|
61
61
|
|
|
62
|
-
To check for decorators, iterate through `field.decorators` and check `decorator.name`. For parsing
|
|
62
|
+
To check for decorators, iterate through `field.decorators` and check `decorator.name`. For parsing
|
|
63
|
+
options, you can write helper functions like the built-in macros do.
|
|
@@ -9,4 +9,4 @@ pub fn my_macro(mut input: TsStream) -> Result<TsStream, MacroforgeError>
|
|
|
9
9
|
| Parameter | Description |
|
|
10
10
|
| ----------------------------------- | ------------------------------------------------------- |
|
|
11
11
|
| `input: TsStream` | Token stream containing the class/interface AST |
|
|
12
|
-
| `Result<TsStream, MacroforgeError>` | Returns generated code or an error with source location |
|
|
12
|
+
| `Result<TsStream, MacroforgeError>` | Returns generated code or an error with source location |
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# ts\_macro\_derive
|
|
2
2
|
|
|
3
|
-
The `#[ts_macro_derive]` attribute is a Rust procedural macro that registers your function as a
|
|
3
|
+
The `#[ts_macro_derive]` attribute is a Rust procedural macro that registers your function as a
|
|
4
|
+
Macroforge derive macro.
|
|
4
5
|
|
|
5
6
|
## Basic Syntax
|
|
6
7
|
|
|
@@ -14,4 +15,4 @@ use macroforge_ts::ts_syn::{TsStream, MacroforgeError};
|
|
|
14
15
|
pub fn my_macro(mut input: TsStream) -> Result<TsStream, MacroforgeError> {
|
|
15
16
|
// Macro implementation
|
|
16
17
|
}
|
|
17
|
-
```
|
|
18
|
+
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# ts\_macro\_derive
|
|
2
2
|
|
|
3
|
-
The `#[ts_macro_derive]` attribute is a Rust procedural macro that registers your function as a
|
|
3
|
+
The `#[ts_macro_derive]` attribute is a Rust procedural macro that registers your function as a
|
|
4
|
+
Macroforge derive macro.
|
|
4
5
|
|
|
5
6
|
## Basic Syntax
|
|
6
7
|
|
|
@@ -230,7 +231,8 @@ struct DecoratorIR {
|
|
|
230
231
|
|
|
231
232
|
Note
|
|
232
233
|
|
|
233
|
-
To check for decorators, iterate through `field.decorators` and check `decorator.name`. For parsing
|
|
234
|
+
To check for decorators, iterate through `field.decorators` and check `decorator.name`. For parsing
|
|
235
|
+
options, you can write helper functions like the built-in macros do.
|
|
234
236
|
|
|
235
237
|
## Adding Imports
|
|
236
238
|
|
|
@@ -255,7 +257,8 @@ Ok(output)
|
|
|
255
257
|
|
|
256
258
|
Note
|
|
257
259
|
|
|
258
|
-
Imports are automatically deduplicated. If the same import already exists in the file, it won't be
|
|
260
|
+
Imports are automatically deduplicated. If the same import already exists in the file, it won't be
|
|
261
|
+
added again.
|
|
259
262
|
|
|
260
263
|
## Returning Errors
|
|
261
264
|
|
|
@@ -333,4 +336,4 @@ pub fn derive_validate(mut input: TsStream) -> Result<TsStream, Macroforg
|
|
|
333
336
|
|
|
334
337
|
## Next Steps
|
|
335
338
|
|
|
336
|
-
|
|
339
|
+
- [Learn the template syntax](../../docs/custom-macros/ts-quote)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Backtick Template Literals: `"'^...^'"`
|
|
2
2
|
|
|
3
|
-
For JavaScript template literals (backtick strings), use the `'^...^'` syntax. This outputs actual
|
|
3
|
+
For JavaScript template literals (backtick strings), use the `'^...^'` syntax. This outputs actual
|
|
4
|
+
backticks and passes through `${"${}"}` for JS interpolation:
|
|
4
5
|
|
|
5
6
|
Rust
|
|
6
7
|
|
|
@@ -20,7 +21,8 @@ TypeScript
|
|
|
20
21
|
const html = `<div>${content}</div>`;
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
You can mix Rust `@{}` interpolation (evaluated at macro expansion time) with JS `${"${}"}`
|
|
24
|
+
You can mix Rust `@{}` interpolation (evaluated at macro expansion time) with JS `${"${}"}`
|
|
25
|
+
interpolation (evaluated at runtime):
|
|
24
26
|
|
|
25
27
|
Rust
|
|
26
28
|
|
|
@@ -38,4 +40,4 @@ TypeScript
|
|
|
38
40
|
|
|
39
41
|
```
|
|
40
42
|
`Hello ${this.name}, you are a User`
|
|
41
|
-
```
|
|
43
|
+
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Comments: `{> "..." <}` and `{>> "..." <<}`
|
|
2
2
|
|
|
3
|
-
Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve
|
|
3
|
+
Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve
|
|
4
|
+
exact spacing in comments:
|
|
4
5
|
|
|
5
6
|
### Block Comments
|
|
6
7
|
|
|
@@ -76,4 +77,4 @@ TypeScript
|
|
|
76
77
|
```
|
|
77
78
|
/** @param {number} userId - The user ID */
|
|
78
79
|
function getUser(userId: number) {}
|
|
79
|
-
```
|
|
80
|
+
```
|
|
@@ -68,14 +68,15 @@ pub fn derive_json_macro(input: TsStream) -> MacroResult {
|
|
|
68
68
|
|
|
69
69
|
## How It Works
|
|
70
70
|
|
|
71
|
-
1.
|
|
72
|
-
2.
|
|
73
|
-
3.
|
|
74
|
-
4.
|
|
71
|
+
1. **Compile-Time:** The template is parsed during macro expansion
|
|
72
|
+
2. **String Building:** Generates Rust code that builds a TypeScript string at runtime
|
|
73
|
+
3. **SWC Parsing:** The generated string is parsed with SWC to produce a typed AST
|
|
74
|
+
4. **Result:** Returns `Stmt` that can be used in `MacroResult` patches
|
|
75
75
|
|
|
76
76
|
## Return Type
|
|
77
77
|
|
|
78
|
-
`ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and
|
|
78
|
+
`ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and
|
|
79
|
+
provides helpful error messages showing the generated TypeScript code if parsing fails:
|
|
79
80
|
|
|
80
81
|
Text
|
|
81
82
|
|
|
@@ -92,8 +93,8 @@ This shows you exactly what was generated, making debugging easy!
|
|
|
92
93
|
|
|
93
94
|
You can mix template syntax with regular TypeScript. Braces `{}` are recognized as either:
|
|
94
95
|
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
- **Template tags** if they start with `#`, `$`, `:`, or `/`
|
|
97
|
+
- **Regular TypeScript blocks** otherwise
|
|
97
98
|
|
|
98
99
|
Rust
|
|
99
100
|
|
|
@@ -120,7 +121,7 @@ ts_template! {
|
|
|
120
121
|
|
|
121
122
|
## Best Practices
|
|
122
123
|
|
|
123
|
-
1.
|
|
124
|
-
2.
|
|
125
|
-
3.
|
|
126
|
-
4.
|
|
124
|
+
1. Use `ts_template!` for complex code generation with loops/conditions
|
|
125
|
+
2. Use `ts_quote!` for simple, static statements
|
|
126
|
+
3. Keep templates readable - extract complex logic into variables
|
|
127
|
+
4. Don't nest templates too deeply - split into helper functions
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
## Identifier Concatenation: `
|
|
1
|
+
## Identifier Concatenation: `content`
|
|
2
2
|
|
|
3
|
-
When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block
|
|
3
|
+
When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block
|
|
4
|
+
syntax. Everything inside `` is concatenated without spaces:
|
|
4
5
|
|
|
5
6
|
Rust
|
|
6
7
|
|
|
@@ -24,7 +25,8 @@ function getUser() {
|
|
|
24
25
|
}
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
Without ident blocks, `@{}` always adds a space after for readability. Use
|
|
28
|
+
Without ident blocks, `@{}` always adds a space after for readability. Use `` when you explicitly
|
|
29
|
+
want concatenation:
|
|
28
30
|
|
|
29
31
|
Rust
|
|
30
32
|
|
|
@@ -17,7 +17,7 @@ let code = ts_template! {
|
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
19
|
User.prototype.toString = function () {
|
|
20
|
-
return
|
|
20
|
+
return 'User instance';
|
|
21
21
|
};
|
|
22
22
|
```
|
|
23
23
|
|
|
@@ -25,7 +25,8 @@ User.prototype.toString = function () {
|
|
|
25
25
|
Identifier Concatenation: `{| content |}`
|
|
26
26
|
</h2>
|
|
27
27
|
|
|
28
|
-
When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block
|
|
28
|
+
When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block
|
|
29
|
+
syntax. Everything inside `{| |}` is concatenated without spaces:
|
|
29
30
|
|
|
30
31
|
```rust
|
|
31
32
|
let field_name = "User";
|
|
@@ -45,7 +46,8 @@ function getUser() {
|
|
|
45
46
|
}
|
|
46
47
|
```
|
|
47
48
|
|
|
48
|
-
Without ident blocks, `@{}` always adds a space after for readability. Use
|
|
49
|
+
Without ident blocks, `@{}` always adds a space after for readability. Use
|
|
50
|
+
`{| |}` when you explicitly want concatenation:
|
|
49
51
|
|
|
50
52
|
```rust
|
|
51
53
|
let name = "Status";
|
|
@@ -71,7 +73,8 @@ ts_template! { @{entity}_@{action} } // → "user_create"
|
|
|
71
73
|
`{>> "..." <<}`
|
|
72
74
|
</h2>
|
|
73
75
|
|
|
74
|
-
Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve
|
|
76
|
+
Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve
|
|
77
|
+
exact spacing in comments:
|
|
75
78
|
|
|
76
79
|
### Block Comments
|
|
77
80
|
|
|
@@ -111,7 +114,7 @@ let code = ts_template! {
|
|
|
111
114
|
/** @param {string} name - The user's name */
|
|
112
115
|
/** @returns {string} A greeting message */
|
|
113
116
|
function greet(name: string): string {
|
|
114
|
-
return
|
|
117
|
+
return 'Hello, ' + name;
|
|
115
118
|
}
|
|
116
119
|
```
|
|
117
120
|
|
|
@@ -141,7 +144,8 @@ function getUser(userId: number) {}
|
|
|
141
144
|
String Interpolation: `"text @{expr}"`
|
|
142
145
|
</h2>
|
|
143
146
|
|
|
144
|
-
Interpolation works automatically inside string literals - no
|
|
147
|
+
Interpolation works automatically inside string literals - no
|
|
148
|
+
<code >format!()</code > needed:
|
|
145
149
|
|
|
146
150
|
```rust
|
|
147
151
|
let name = "World";
|
|
@@ -156,8 +160,8 @@ let code = ts_template! {
|
|
|
156
160
|
**Generates:**
|
|
157
161
|
|
|
158
162
|
```typescript
|
|
159
|
-
console.log(
|
|
160
|
-
console.log(
|
|
163
|
+
console.log('Hello World!');
|
|
164
|
+
console.log('Count: 42, doubled: 84');
|
|
161
165
|
```
|
|
162
166
|
|
|
163
167
|
This also works with method calls and complex expressions:
|
|
@@ -174,7 +178,9 @@ let code = ts_template! {
|
|
|
174
178
|
Backtick Template Literals: `"'^...^'"`
|
|
175
179
|
</h2>
|
|
176
180
|
|
|
177
|
-
For JavaScript template literals (backtick strings), use the
|
|
181
|
+
For JavaScript template literals (backtick strings), use the
|
|
182
|
+
<code >'^...^'</code > syntax. This outputs actual backticks and passes through `${"${}"}` for JS
|
|
183
|
+
interpolation:
|
|
178
184
|
|
|
179
185
|
```rust
|
|
180
186
|
let tag_name = "div";
|
|
@@ -188,7 +194,8 @@ let code = ts_template! {
|
|
|
188
194
|
|
|
189
195
|
<CodeBlock code={"const html = `${content}`;"} lang="typescript" />
|
|
190
196
|
|
|
191
|
-
You can mix Rust `@{}` interpolation (evaluated at macro expansion time) with JS
|
|
197
|
+
You can mix Rust `@{}` interpolation (evaluated at macro expansion time) with JS
|
|
198
|
+
`${"${}"}` interpolation (evaluated at runtime):
|
|
192
199
|
|
|
193
200
|
```rust
|
|
194
201
|
let class_name = "User";
|
|
@@ -272,7 +279,7 @@ let code = ts_template! {
|
|
|
272
279
|
**Generates:**
|
|
273
280
|
|
|
274
281
|
```typescript
|
|
275
|
-
console.log(
|
|
282
|
+
console.log('Hello, Alice!');
|
|
276
283
|
```
|
|
277
284
|
|
|
278
285
|
This is useful when working with optional values from your IR:
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Template Syntax
|
|
2
2
|
|
|
3
|
-
The `macroforge_ts_quote` crate provides template-based code generation for TypeScript. The
|
|
3
|
+
The `macroforge_ts_quote` crate provides template-based code generation for TypeScript. The
|
|
4
|
+
`ts_template!` macro uses Svelte + Rust-inspired syntax for control flow and interpolation, making
|
|
5
|
+
it easy to generate complex TypeScript code.
|
|
4
6
|
|
|
5
7
|
## Available Macros
|
|
6
8
|
|
|
7
9
|
| Macro | Output | Use Case |
|
|
8
10
|
| -------------- | ------------------- | ----------------------- |
|
|
9
11
|
| `ts_template!` | Any TypeScript code | General code generation |
|
|
10
|
-
| `body!` | Class body members | Methods and properties |
|
|
12
|
+
| `body!` | Class body members | Methods and properties |
|
|
@@ -17,7 +17,7 @@ let code = ts_template! {
|
|
|
17
17
|
**Generates:**
|
|
18
18
|
|
|
19
19
|
```typescript
|
|
20
|
-
console.log(
|
|
20
|
+
console.log('Hello, Alice!');
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
This is useful when working with optional values from your IR:
|
|
@@ -30,4 +30,4 @@ let code = ts_template! {
|
|
|
30
30
|
this.@{field.name} = undefined;
|
|
31
31
|
{/if}
|
|
32
32
|
};
|
|
33
|
-
```
|
|
33
|
+
```
|
|
@@ -1,28 +1,29 @@
|
|
|
1
1
|
## Quick Reference
|
|
2
2
|
|
|
3
|
-
| Syntax | Description
|
|
4
|
-
| -------------------------------------------------------------- |
|
|
5
|
-
| `@{expr}` | Interpolate a Rust expression (adds space after)
|
|
3
|
+
| Syntax | Description |
|
|
4
|
+
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
|
|
5
|
+
| `@{expr}` | Interpolate a Rust expression (adds space after) |
|
|
6
6
|
| `{| content |}` | Ident block: concatenates without spaces (e.g., `{|get@{name}|}` → `getUser`) |
|
|
7
|
-
| `{> "comment" <}` | Block comment: outputs `/* comment */` (string preserves whitespace)
|
|
8
|
-
| `{>> "doc" <<}` | Doc comment: outputs `/** doc */` (string preserves whitespace)
|
|
9
|
-
| `@@{` | Escape for literal `@{` (e.g., `"@@{foo}"` → `@{foo}`)
|
|
10
|
-
| `"text @{expr}"` | String interpolation (auto-detected)
|
|
11
|
-
| `"'^template ${js}^'"` | JS backtick template literal (outputs `` `template ${js}` ``)
|
|
12
|
-
| `{#if cond}...{/if}` | Conditional block
|
|
13
|
-
| `{#if cond}...{:else}...{/if}` | Conditional with else
|
|
14
|
-
| `{#if a}...{:else if b}...{:else}...{/if}` | Full if/else-if/else chain
|
|
15
|
-
| `{#if let pattern = expr}...{/if}` | Pattern matching if-let
|
|
16
|
-
| `{#match expr}{:case pattern}...{/match}` | Match expression with case arms
|
|
17
|
-
| `{#for item in list}...{/for}` | Iterate over a collection
|
|
18
|
-
| `{#while cond}...{/while}` | While loop
|
|
19
|
-
| `{#while let pattern = expr}...{/while}` | While-let pattern matching loop
|
|
20
|
-
| `{$let name = expr}` | Define a local constant
|
|
21
|
-
| `{$let mut name = expr}` | Define a mutable local variable
|
|
22
|
-
| `{$do expr}` | Execute a side-effectful expression
|
|
23
|
-
| `{$typescript stream}` | Inject a TsStream, preserving its source and runtime\_patches (imports)
|
|
24
|
-
|
|
25
|
-
**Note:** A single `@` not followed by `{` passes through unchanged (e.g., `email@domain.com` works
|
|
7
|
+
| `{> "comment" <}` | Block comment: outputs `/* comment */` (string preserves whitespace) |
|
|
8
|
+
| `{>> "doc" <<}` | Doc comment: outputs `/** doc */` (string preserves whitespace) |
|
|
9
|
+
| `@@{` | Escape for literal `@{` (e.g., `"@@{foo}"` → `@{foo}`) |
|
|
10
|
+
| `"text @{expr}"` | String interpolation (auto-detected) |
|
|
11
|
+
| `"'^template ${js}^'"` | JS backtick template literal (outputs `` `template ${js}` ``) |
|
|
12
|
+
| `{#if cond}...{/if}` | Conditional block |
|
|
13
|
+
| `{#if cond}...{:else}...{/if}` | Conditional with else |
|
|
14
|
+
| `{#if a}...{:else if b}...{:else}...{/if}` | Full if/else-if/else chain |
|
|
15
|
+
| `{#if let pattern = expr}...{/if}` | Pattern matching if-let |
|
|
16
|
+
| `{#match expr}{:case pattern}...{/match}` | Match expression with case arms |
|
|
17
|
+
| `{#for item in list}...{/for}` | Iterate over a collection |
|
|
18
|
+
| `{#while cond}...{/while}` | While loop |
|
|
19
|
+
| `{#while let pattern = expr}...{/while}` | While-let pattern matching loop |
|
|
20
|
+
| `{$let name = expr}` | Define a local constant |
|
|
21
|
+
| `{$let mut name = expr}` | Define a mutable local variable |
|
|
22
|
+
| `{$do expr}` | Execute a side-effectful expression |
|
|
23
|
+
| `{$typescript stream}` | Inject a TsStream, preserving its source and runtime\_patches (imports) |
|
|
24
|
+
|
|
25
|
+
**Note:** A single `@` not followed by `{` passes through unchanged (e.g., `email@domain.com` works
|
|
26
|
+
as expected).
|
|
26
27
|
|
|
27
28
|
## Interpolation: `@{expr}`
|
|
28
29
|
|
|
@@ -49,4 +50,4 @@ TypeScript
|
|
|
49
50
|
User.prototype.toString = function () {
|
|
50
51
|
return "User instance";
|
|
51
52
|
};
|
|
52
|
-
```
|
|
53
|
+
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## Side Effects: `{$do}`
|
|
2
2
|
|
|
3
|
-
Execute an expression for its side effects without producing output. This is commonly used with
|
|
3
|
+
Execute an expression for its side effects without producing output. This is commonly used with
|
|
4
|
+
mutable variables:
|
|
4
5
|
|
|
5
6
|
Rust
|
|
6
7
|
|
|
@@ -16,7 +17,7 @@ let code = ts_template! {
|
|
|
16
17
|
|
|
17
18
|
Common uses for `{$do}`:
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
- Incrementing counters: `{$do i += 1}`
|
|
21
|
+
- Building collections: `{$do vec.push(item)}`
|
|
22
|
+
- Setting flags: `{$do found = true}`
|
|
23
|
+
- Any mutating operation
|
|
@@ -15,8 +15,8 @@ let code = ts_template! {
|
|
|
15
15
|
**Generates:**
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
|
-
console.log(
|
|
19
|
-
console.log(
|
|
18
|
+
console.log('Hello World!');
|
|
19
|
+
console.log('Count: 42, doubled: 84');
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
This also works with method calls and complex expressions:
|
|
@@ -27,4 +27,4 @@ let field = "username";
|
|
|
27
27
|
let code = ts_template! {
|
|
28
28
|
throw new Error("Invalid @{field.to_uppercase()}");
|
|
29
29
|
};
|
|
30
|
-
```
|
|
30
|
+
```
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
## TsStream Injection: `{$typescript}`
|
|
2
2
|
|
|
3
|
-
Inject another TsStream into your template, preserving both its source code and runtime patches
|
|
3
|
+
Inject another TsStream into your template, preserving both its source code and runtime patches
|
|
4
|
+
(like imports added via `add_import()`):
|
|
4
5
|
|
|
5
6
|
Rust
|
|
6
7
|
|
|
@@ -66,4 +67,4 @@ TypeScript
|
|
|
66
67
|
```
|
|
67
68
|
// This outputs a literal @{foo}
|
|
68
69
|
const example = "Use @{foo} for templates";
|
|
69
|
-
```
|
|
70
|
+
```
|