@macroforge/mcp-server 0.1.42 → 0.1.50

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.
Files changed (71) hide show
  1. package/LICENSE +22 -0
  2. package/docs/BOOK.md +165 -0
  3. package/docs/api/api-overview.md +67 -48
  4. package/docs/api/expand-sync.md +88 -53
  5. package/docs/api/native-plugin.md +121 -71
  6. package/docs/api/position-mapper.md +115 -55
  7. package/docs/api/transform-sync.md +86 -60
  8. package/docs/builtin-macros/clone.md +0 -20
  9. package/docs/builtin-macros/debug.md +0 -23
  10. package/docs/builtin-macros/default.md +1 -40
  11. package/docs/builtin-macros/deserialize/example.md +8 -1416
  12. package/docs/builtin-macros/deserialize.md +8 -1416
  13. package/docs/builtin-macros/hash.md +0 -42
  14. package/docs/builtin-macros/macros-overview/detailed-documentation.md +13 -0
  15. package/docs/builtin-macros/macros-overview/enum-support.md +30 -0
  16. package/docs/builtin-macros/macros-overview/interface-support.md +28 -0
  17. package/docs/builtin-macros/macros-overview/overview.md +36 -0
  18. package/docs/builtin-macros/macros-overview/type-alias-support.md +62 -0
  19. package/docs/builtin-macros/macros-overview.md +171 -130
  20. package/docs/builtin-macros/ord.md +0 -25
  21. package/docs/builtin-macros/partial-eq.md +0 -84
  22. package/docs/builtin-macros/partial-ord.md +2 -32
  23. package/docs/builtin-macros/serialize.md +2 -62
  24. package/docs/concepts/architecture.md +125 -48
  25. package/docs/concepts/derive-system/built-in-vs-custom-macros.md +13 -0
  26. package/docs/concepts/derive-system/overview.md +200 -0
  27. package/docs/concepts/derive-system.md +157 -104
  28. package/docs/concepts/how-macros-work.md +98 -47
  29. package/docs/custom-macros/custom-overview.md +79 -57
  30. package/docs/custom-macros/rust-setup.md +138 -99
  31. package/docs/custom-macros/ts-macro-derive/accessing-field-data.md +40 -31
  32. package/docs/custom-macros/ts-macro-derive/adding-imports.md +14 -11
  33. package/docs/custom-macros/ts-macro-derive/attribute-options.md +20 -25
  34. package/docs/custom-macros/ts-macro-derive/complete-example.md +40 -38
  35. package/docs/custom-macros/ts-macro-derive/deriveinput-structure.md +49 -47
  36. package/docs/custom-macros/ts-macro-derive/function-signature.md +12 -0
  37. package/docs/custom-macros/ts-macro-derive/overview.md +9 -7
  38. package/docs/custom-macros/ts-macro-derive/parsing-input.md +20 -18
  39. package/docs/custom-macros/ts-macro-derive/returning-errors.md +15 -13
  40. package/docs/custom-macros/ts-macro-derive.md +322 -228
  41. package/docs/custom-macros/ts-quote/backtick-template-literals.md +19 -7
  42. package/docs/custom-macros/ts-quote/comments-and.md +56 -22
  43. package/docs/custom-macros/ts-quote/complete-example-json-derive-macro.md +89 -98
  44. package/docs/custom-macros/ts-quote/conditionals-ifif.md +35 -29
  45. package/docs/custom-macros/ts-quote/identifier-concatenation-content.md +30 -22
  46. package/docs/custom-macros/ts-quote/iteration-for.md +48 -40
  47. package/docs/custom-macros/ts-quote/local-constants-let.md +23 -21
  48. package/docs/custom-macros/ts-quote/match-expressions-match.md +46 -38
  49. package/docs/custom-macros/ts-quote/overview.md +5 -10
  50. package/docs/custom-macros/ts-quote/pattern-matching-iflet.md +39 -0
  51. package/docs/custom-macros/ts-quote/quick-reference.md +50 -129
  52. package/docs/custom-macros/ts-quote/side-effects-do.md +13 -78
  53. package/docs/custom-macros/ts-quote/string-interpolation-textexpr.md +36 -0
  54. package/docs/custom-macros/ts-quote/tsstream-injection-typescript.md +43 -35
  55. package/docs/custom-macros/ts-quote/while-loops-while.md +31 -23
  56. package/docs/custom-macros/ts-quote.md +800 -520
  57. package/docs/getting-started/first-macro.md +98 -71
  58. package/docs/getting-started/installation.md +109 -65
  59. package/docs/integration/cli.md +214 -105
  60. package/docs/integration/configuration.md +115 -72
  61. package/docs/integration/integration-overview.md +55 -18
  62. package/docs/integration/mcp-server.md +84 -43
  63. package/docs/integration/svelte-preprocessor.md +183 -126
  64. package/docs/integration/typescript-plugin.md +101 -53
  65. package/docs/integration/vite-plugin.md +116 -76
  66. package/docs/language-servers/ls-overview.md +37 -21
  67. package/docs/language-servers/svelte.md +69 -38
  68. package/docs/language-servers/zed.md +81 -44
  69. package/docs/roadmap/roadmap.md +75 -53
  70. package/docs/sections.json +1 -242
  71. package/package.json +27 -28
@@ -1,45 +1,79 @@
1
- ## Comments: `&#123;> "..." <&#125;` and `&#123;>> "..." <<&#125;`
1
+ ## Comments: `{> "..." <}` and `{>> "..." <<}`
2
2
 
3
3
  Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve exact spacing in comments:
4
4
 
5
5
  ### Block Comments
6
6
 
7
- Use `&#123;> "comment" <&#125;` for block comments:
7
+ Use `{> "comment" <}` for block comments:
8
8
 
9
- ```rust
10
- let code = ts_template! {
11
- {> "This is a block comment" <}
12
- const x = 42;
9
+ Rust
10
+
11
+ ```
12
+ let code = ts_template! {
13
+     {> "This is a block comment" <}
14
+     const x = 42;
13
15
  };
14
16
  ```
15
17
 
16
18
  **Generates:**
17
19
 
18
- ```typescript
19
- /* This is a block comment */
20
- const x = 42;
20
+ TypeScript
21
+
22
+ ```
23
+ /* This is a block comment */
24
+ const x = 42;
21
25
  ```
22
26
 
23
27
  ### Doc Comments (JSDoc)
24
28
 
25
- Use `&#123;>> "doc" <<&#125;` for JSDoc comments:
29
+ Use `{>> "doc" <<}` for JSDoc comments:
30
+
31
+ Rust
26
32
 
27
- ```rust
28
- let code = ts_template! {
29
- {>> "@param {string} name - The user's name" <<}
30
- {>> "@returns {string} A greeting message" <<}
31
- function greet(name: string): string {
32
- return "Hello, " + name;
33
- }
33
+ ```
34
+ let code = ts_template! {
35
+     {>> "@param {string} name - The user's name" <<}
36
+     {>> "@returns {string} A greeting message" <<}
37
+     function greet(name: string): string {
38
+         return "Hello, " + name;
39
+     }
34
40
  };
35
41
  ```
36
42
 
37
43
  **Generates:**
38
44
 
39
- ```typescript
40
- /** @param {string} name - The user's name */
41
- /** @returns {string} A greeting message */
42
- function greet(name: string): string {
43
- return "Hello, " + name;
45
+ TypeScript
46
+
47
+ ```
48
+ /** @param {string} name - The user's name */
49
+ /** @returns {string} A greeting message */
50
+ function greet(name: string): string {
51
+     return "Hello, " + name;
44
52
  }
53
+ ```
54
+
55
+ ### Comments with Interpolation
56
+
57
+ Use `format!()` or similar to build dynamic comment strings:
58
+
59
+ Rust
60
+
61
+ ```
62
+ let param_name = "userId";
63
+ let param_type = "number";
64
+ let comment = format!("@param {{{}}} {} - The user ID", param_type, param_name);
65
+
66
+ let code = ts_template! {
67
+     {>> @{comment} <<}
68
+     function getUser(userId: number) {}
69
+ };
70
+ ```
71
+
72
+ **Generates:**
73
+
74
+ TypeScript
75
+
76
+ ```
77
+ /** @param {number} userId - The user ID */
78
+ function getUser(userId: number) {}
45
79
  ```
@@ -4,82 +4,85 @@ Here's a comparison showing how `ts_template!` simplifies code generation:
4
4
 
5
5
  ### Before (Manual AST Building)
6
6
 
7
- ```rust
8
- pub fn derive_json_macro(input: TsStream) -> MacroResult {
9
- let input = parse_ts_macro_input!(input as DeriveInput);
10
-
11
- match &input.data {
12
- Data::Class(class) => {
13
- let class_name = input.name();
14
-
15
- let mut body_stmts = vec![ts_quote!( const result = {}; as Stmt )];
16
-
17
- for field_name in class.field_names() {
18
- body_stmts.push(ts_quote!(
19
- result.$(ident!("{}", field_name)) = this.$(ident!("{}", field_name));
20
- as Stmt
21
- ));
22
- }
23
-
24
- body_stmts.push(ts_quote!( return result; as Stmt ));
25
-
26
- let runtime_code = fn_assign!(
27
- member_expr!(Expr::Ident(ident!(class_name)), "prototype"),
28
- "toJSON",
29
- body_stmts
30
- );
31
-
32
- // ...
33
- }
34
- }
35
- }
7
+ Rust
8
+
36
9
  ```
10
+ pub fn derive_json_macro(input: TsStream) -> MacroResult {
11
+     let input = parse_ts_macro_input!(input as DeriveInput);
12
+
13
+     match &input.data {
14
+         Data::Class(class) => {
15
+             let class_name = input.name();
16
+
17
+             let mut body_stmts = vec![ts_quote!( const result = {}; as Stmt )];
18
+
19
+             for field_name in class.field_names() {
20
+                 body_stmts.push(ts_quote!(
21
+                     result.$(ident!("{}", field_name)) = this.$(ident!("{}", field_name));
22
+                     as Stmt
23
+                 ));
24
+             }
37
25
 
38
- ### After (With ts_template!)
39
-
40
- ```rust
41
- pub fn derive_json_macro(input: TsStream) -> MacroResult {
42
- let input = parse_ts_macro_input!(input as DeriveInput);
43
-
44
- match &input.data {
45
- Data::Class(class) => {
46
- let class_name = input.name();
47
- let fields = class.field_names();
48
-
49
- let runtime_code = ts_template! {
50
- @{class_name}.prototype.toJSON = function() {
51
- const result = {};
52
- {#for field in fields}
53
- result.@{field} = this.@{field};
54
- {/for}
55
- return result;
56
- };
57
- };
58
-
59
- // ...
60
- }
61
- }
26
+             body_stmts.push(ts_quote!( return result; as Stmt ));
27
+
28
+             let runtime_code = fn_assign!(
29
+                 member_expr!(Expr::Ident(ident!(class_name)), "prototype"),
30
+                 "toJSON",
31
+                 body_stmts
32
+             );
33
+
34
+             // ...
35
+         }
36
+     }
62
37
  }
63
38
  ```
64
39
 
65
- ## How It Works
40
+ ### After (With ts\_template!)
66
41
 
67
- 1. **Compile-Time:** The template is parsed during macro expansion
42
+ Rust
68
43
 
69
- 2. **String Building:** Generates Rust code that builds a TypeScript string at runtime
44
+ ```
45
+ pub fn derive_json_macro(input: TsStream) -> MacroResult {
46
+     let input = parse_ts_macro_input!(input as DeriveInput);
47
+
48
+     match &input.data {
49
+         Data::Class(class) => {
50
+             let class_name = input.name();
51
+             let fields = class.field_names();
52
+
53
+             let runtime_code = ts_template! {
54
+                 @{class_name}.prototype.toJSON = function() {
55
+                     const result = {};
56
+                     {#for field in fields}
57
+                         result.@{field} = this.@{field};
58
+                     {/for}
59
+                     return result;
60
+                 };
61
+             };
62
+
63
+             // ...
64
+         }
65
+     }
66
+ }
67
+ ```
70
68
 
71
- 3. **SWC Parsing:** The generated string is parsed with SWC to produce a typed AST
69
+ ## How It Works
72
70
 
73
- 4. **Result:** Returns `Stmt` that can be used in `MacroResult` patches
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
74
75
 
75
76
  ## Return Type
76
77
 
77
- `ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and provides helpful error messages showing the generated TypeScript code if parsing fails:
78
+ `ts_template!` returns a `Result<Stmt, TsSynError>` by default. The macro automatically unwraps and provides helpful error messages showing the generated TypeScript code if parsing fails:
79
+
80
+ Text
78
81
 
79
- ```text
80
- Failed to parse generated TypeScript:
81
- User.prototype.toJSON = function( {
82
- return {};
82
+ ```
83
+ Failed to parse generated TypeScript:
84
+ User.prototype.toJSON = function( {
85
+     return {};
83
86
  }
84
87
  ```
85
88
 
@@ -87,49 +90,37 @@ This shows you exactly what was generated, making debugging easy!
87
90
 
88
91
  ## Nesting and Regular TypeScript
89
92
 
90
- You can mix template syntax with regular TypeScript. Braces <code >&#123;&#125;</code > are recognized as either:
93
+ You can mix template syntax with regular TypeScript. Braces `{}` are recognized as either:
91
94
 
92
- - **Template tags** if they start with `#`, `$`, `:`, or `/`
95
+ * **Template tags** if they start with `#`, `$`, `:`, or `/`
96
+ * **Regular TypeScript blocks** otherwise
93
97
 
94
- - **Regular TypeScript blocks** otherwise
98
+ Rust
95
99
 
96
- ```rust
97
- ts_template! {
98
- const config = {
99
- {#if use_strict}
100
- strict: true,
101
- {:else}
102
- strict: false,
103
- {/if}
104
- timeout: 5000
105
- };
100
+ ```
101
+ ts_template! {
102
+     const config = {
103
+         {#if use_strict}
104
+             strict: true,
105
+         {:else}
106
+             strict: false,
107
+         {/if}
108
+         timeout: 5000
109
+     };
106
110
  }
107
111
  ```
108
112
 
109
113
  ## Comparison with Alternatives
110
114
 
111
- | `ts_quote!`
112
- | Compile-time validation, type-safe
113
- | Can't handle Vec<Stmt>, verbose
114
-
115
-
116
-
117
- | `parse_ts_str()`
118
- | Maximum flexibility
119
- | Runtime parsing, less readable
120
-
121
-
122
-
123
- | `ts_template!`
124
- | Readable, handles loops/conditions
125
- | Small runtime parsing overhead
115
+ | Approach | Pros | Cons |
116
+ | ---------------- | ---------------------------------- | -------------------------------- |
117
+ | `ts_quote!` | Compile-time validation, type-safe | Can't handle Vec\<Stmt>, verbose |
118
+ | `parse_ts_str()` | Maximum flexibility | Runtime parsing, less readable |
119
+ | `ts_template!` | Readable, handles loops/conditions | Small runtime parsing overhead |
126
120
 
127
121
  ## Best Practices
128
122
 
129
- 1. Use `ts_template!` for complex code generation with loops/conditions
130
-
131
- 2. Use `ts_quote!` for simple, static statements
132
-
133
- 3. Keep templates readable - extract complex logic into variables
134
-
135
- 4. Don't nest templates too deeply - split into helper functions
123
+ 1. Use `ts_template!` for complex code generation with loops/conditions
124
+ 2. Use `ts_quote!` for simple, static statements
125
+ 3. Keep templates readable - extract complex logic into variables
126
+ 4. Don't nest templates too deeply - split into helper functions
@@ -1,46 +1,52 @@
1
- ## Conditionals: `&#123;#if&#125;...&#123;/if&#125;`
1
+ ## Conditionals: `{#if}...{/if}`
2
2
 
3
3
  Basic conditional:
4
4
 
5
- ```rust
6
- let needs_validation = true;
5
+ Rust
7
6
 
8
- let code = ts_template! {
9
- function save() {
10
- {#if needs_validation}
11
- if (!this.isValid()) return false;
12
- {/if}
13
- return this.doSave();
14
- }
7
+ ```
8
+ let needs_validation = true;
9
+
10
+ let code = ts_template! {
11
+     function save() {
12
+         {#if needs_validation}
13
+             if (!this.isValid()) return false;
14
+         {/if}
15
+         return this.doSave();
16
+     }
15
17
  };
16
18
  ```
17
19
 
18
20
  ### If-Else
19
21
 
20
- ```rust
21
- let has_default = true;
22
+ Rust
22
23
 
23
- let code = ts_template! {
24
- {#if has_default}
25
- return defaultValue;
26
- {:else}
27
- throw new Error("No default");
28
- {/if}
24
+ ```
25
+ let has_default = true;
26
+
27
+ let code = ts_template! {
28
+     {#if has_default}
29
+         return defaultValue;
30
+     {:else}
31
+         throw new Error("No default");
32
+     {/if}
29
33
  };
30
34
  ```
31
35
 
32
36
  ### If-Else-If Chains
33
37
 
34
- ```rust
35
- let level = 2;
36
-
37
- let code = ts_template! {
38
- {#if level == 1}
39
- console.log("Level 1");
40
- {:else if level == 2}
41
- console.log("Level 2");
42
- {:else}
43
- console.log("Other level");
44
- {/if}
38
+ Rust
39
+
40
+ ```
41
+ let level = 2;
42
+
43
+ let code = ts_template! {
44
+     {#if level == 1}
45
+         console.log("Level 1");
46
+     {:else if level == 2}
47
+         console.log("Level 2");
48
+     {:else}
49
+         console.log("Other level");
50
+     {/if}
45
51
  };
46
52
  ```
@@ -1,42 +1,50 @@
1
- ## Identifier Concatenation: `&#123;| content |&#125;`
1
+ ## Identifier Concatenation: `{| content |}`
2
2
 
3
- When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block syntax. Everything inside `&#123;| |&#125;` is concatenated without spaces:
3
+ When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block syntax. Everything inside `{| |}` is concatenated without spaces:
4
4
 
5
- ```rust
6
- let field_name = "User";
5
+ Rust
7
6
 
8
- let code = ts_template! {
9
- function {|get@{field_name}|}() {
10
- return this.@{field_name.to_lowercase()};
11
- }
7
+ ```
8
+ let field_name = "User";
9
+
10
+ let code = ts_template! {
11
+     function {|get@{field_name}|}() {
12
+         return this.@{field_name.to_lowercase()};
13
+     }
12
14
  };
13
15
  ```
14
16
 
15
17
  **Generates:**
16
18
 
17
- ```typescript
18
- function getUser() {
19
- return this.user;
19
+ TypeScript
20
+
21
+ ```
22
+ function getUser() {
23
+   return this.user;
20
24
  }
21
25
  ```
22
26
 
23
- Without ident blocks, `@&#123;&#125;` always adds a space after for readability. Use `&#123;| |&#125;` when you explicitly want concatenation:
27
+ Without ident blocks, `@{}` always adds a space after for readability. Use `{| |}` when you explicitly want concatenation:
24
28
 
25
- ```rust
26
- let name = "Status";
29
+ Rust
27
30
 
28
- // With space (default behavior)
29
- ts_template! { namespace @{name} } // → "namespace Status"
31
+ ```
32
+ let name = "Status";
33
+
34
+ // With space (default behavior)
35
+ ts_template! { namespace @{name} }  // → "namespace Status"
30
36
 
31
- // Without space (ident block)
32
- ts_template! { {|namespace@{name}|} } // "namespaceStatus"
37
+ // Without space (ident block)
38
+ ts_template! { {|namespace@{name}|} }  //  "namespaceStatus"
33
39
  ```
34
40
 
35
41
  Multiple interpolations can be combined:
36
42
 
37
- ```rust
38
- let entity = "user";
39
- let action = "create";
43
+ Rust
44
+
45
+ ```
46
+ let entity = "user";
47
+ let action = "create";
40
48
 
41
- ts_template! { {|@{entity}_@{action}|} } // "user_create"
49
+ ts_template! { {|@{entity}_@{action}|} }  //  "user_create"
42
50
  ```
@@ -1,60 +1,68 @@
1
- ## Iteration: `&#123;#for&#125;`
2
-
3
- ```rust
4
- let fields = vec!["name", "email", "age"];
5
-
6
- let code = ts_template! {
7
- function toJSON() {
8
- const result = {};
9
- {#for field in fields}
10
- result.@{field} = this.@{field};
11
- {/for}
12
- return result;
13
- }
1
+ ## Iteration: `{#for}`
2
+
3
+ Rust
4
+
5
+ ```
6
+ let fields = vec!["name", "email", "age"];
7
+
8
+ let code = ts_template! {
9
+     function toJSON() {
10
+         const result = {};
11
+         {#for field in fields}
12
+             result.@{field} = this.@{field};
13
+         {/for}
14
+         return result;
15
+     }
14
16
  };
15
17
  ```
16
18
 
17
19
  **Generates:**
18
20
 
19
- ```typescript
20
- function toJSON() {
21
- const result = {};
22
- result.name = this.name;
23
- result.email = this.email;
24
- result.age = this.age;
25
- return result;
21
+ TypeScript
22
+
23
+ ```
24
+ function toJSON() {
25
+   const result = {};
26
+   result.name = this.name;
27
+   result.email = this.email;
28
+   result.age = this.age;
29
+   return result;
26
30
  }
27
31
  ```
28
32
 
29
33
  ### Tuple Destructuring in Loops
30
34
 
31
- ```rust
32
- let items = vec![("user", "User"), ("post", "Post")];
35
+ Rust
36
+
37
+ ```
38
+ let items = vec![("user", "User"), ("post", "Post")];
33
39
 
34
- let code = ts_template! {
35
- {#for (key, class_name) in items}
36
- const @{key} = new @{class_name}();
37
- {/for}
40
+ let code = ts_template! {
41
+     {#for (key, class_name) in items}
42
+         const @{key} = new @{class_name}();
43
+     {/for}
38
44
  };
39
45
  ```
40
46
 
41
47
  ### Nested Iterations
42
48
 
43
- ```rust
44
- let classes = vec![
45
- ("User", vec!["name", "email"]),
46
- ("Post", vec!["title", "content"]),
49
+ Rust
50
+
51
+ ```
52
+ let classes = vec![
53
+     ("User", vec!["name", "email"]),
54
+     ("Post", vec!["title", "content"]),
47
55
  ];
48
56
 
49
- ts_template! {
50
- {#for (class_name, fields) in classes}
51
- @{class_name}.prototype.toJSON = function() {
52
- return {
53
- {#for field in fields}
54
- @{field}: this.@{field},
55
- {/for}
56
- };
57
- };
58
- {/for}
57
+ ts_template! {
58
+     {#for (class_name, fields) in classes}
59
+         @{class_name}.prototype.toJSON = function() {
60
+             return {
61
+                 {#for field in fields}
62
+                     @{field}: this.@{field},
63
+                 {/for}
64
+             };
65
+         };
66
+     {/for}
59
67
  }
60
68
  ```
@@ -1,34 +1,36 @@
1
- ## Local Constants: `&#123;$let&#125;`
1
+ ## Local Constants: `{$let}`
2
2
 
3
3
  Define local variables within the template scope:
4
4
 
5
- ```rust
6
- let items = vec![("user", "User"), ("post", "Post")];
5
+ Rust
7
6
 
8
- let code = ts_template! {
9
- {#for (key, class_name) in items}
10
- {$let upper = class_name.to_uppercase()}
11
- console.log("Processing @{upper}");
12
- const @{key} = new @{class_name}();
13
- {/for}
7
+ ```
8
+ let items = vec![("user", "User"), ("post", "Post")];
9
+
10
+ let code = ts_template! {
11
+     {#for (keyclass_name) in items}
12
+         {$let upper = class_name.to_uppercase()}
13
+         console.log("Processing @{upper}");
14
+         const @{key} = new @{class_name}();
15
+     {/for}
14
16
  };
15
17
  ```
16
18
 
17
19
  This is useful for computing derived values inside loops without cluttering the Rust code.
18
20
 
19
- <h2 id="mutable-variables">
20
- Mutable Variables: `&#123;$let mut&#125;`
21
- </h2>
21
+ ## Mutable Variables: `{$let mut}`
22
22
 
23
- When you need to modify a variable within the template (e.g., in a <code >while</code > loop), use `&#123;$let mut&#125;`:
23
+ When you need to modify a variable within the template (e.g., in a `while` loop), use `{$let mut}`:
24
24
 
25
- ```rust
26
- let code = ts_template! {
27
- {$let mut count = 0}
28
- {#for item in items}
29
- console.log("Item @{count}: @{item}");
30
- {$do count += 1}
31
- {/for}
32
- console.log("Total: @{count}");
25
+ Rust
26
+
27
+ ```
28
+ let code = ts_template! {
29
+     {$let mut count = 0}
30
+     {#for item in items}
31
+         console.log("Item @{count}: @{item}");
32
+         {$do count += 1}
33
+     {/for}
34
+     console.log("Total: @{count}");
33
35
  };
34
36
  ```