Skip to main content
Glama
interpolation-expr.md6.87 kB
## Interpolation: `@&#123;expr&#125;` Insert Rust expressions into the generated TypeScript: ```rust let class_name = "User"; let method = "toString"; let code = ts_template! { @{class_name}.prototype.@{method} = function() { return "User instance"; }; }; ``` **Generates:** ```typescript User.prototype.toString = function () { return "User instance"; }; ``` <h2 id="ident-blocks"> Identifier Concatenation: `&#123;| content |&#125;` </h2> When you need to build identifiers dynamically (like `getUser`, `setName`), use the ident block syntax. Everything inside `&#123;| |&#125;` is concatenated without spaces: ```rust let field_name = "User"; let code = ts_template! { function {|get@{field_name}|}() { return this.@{field_name.to_lowercase()}; } }; ``` **Generates:** ```typescript function getUser() { return this.user; } ``` Without ident blocks, `@&#123;&#125;` always adds a space after for readability. Use `&#123;| |&#125;` when you explicitly want concatenation: ```rust let name = "Status"; // With space (default behavior) ts_template! { namespace @{name} } // → "namespace Status" // Without space (ident block) ts_template! { {|namespace@{name}|} } // → "namespaceStatus" ``` Multiple interpolations can be combined: ```rust let entity = "user"; let action = "create"; ts_template! { {|@{entity}_@{action}|} } // → "user_create" ``` <h2 id="comments"> Comments: `&#123;> "..." <&#125;` and `&#123;>> "..." <<&#125;` </h2> Since Rust's tokenizer strips whitespace before macros see them, use string literals to preserve exact spacing in comments: ### Block Comments Use `&#123;> "comment" <&#125;` for block comments: ```rust let code = ts_template! { {> "This is a block comment" <} const x = 42; }; ``` **Generates:** ```typescript /* This is a block comment */ const x = 42; ``` ### Doc Comments (JSDoc) Use `&#123;>> "doc" <<&#125;` for JSDoc comments: ```rust let code = ts_template! { {>> "@param {string} name - The user's name" <<} {>> "@returns {string} A greeting message" <<} function greet(name: string): string { return "Hello, " + name; } }; ``` **Generates:** ```typescript /** @param {string} name - The user's name */ /** @returns {string} A greeting message */ function greet(name: string): string { return "Hello, " + name; } ``` ### Comments with Interpolation Use `format!()` or similar to build dynamic comment strings: ```rust let param_name = "userId"; let param_type = "number"; let comment = format!("@param {{{}}} {} - The user ID", param_type, param_name); let code = ts_template! { {>> @{comment} <<} function getUser(userId: number) {} }; ``` **Generates:** ```typescript /** @param {number} userId - The user ID */ function getUser(userId: number) {} ``` <h2 id="string-interpolation"> String Interpolation: `"text @&#123;expr&#125;"` </h2> Interpolation works automatically inside string literals - no <code >format!()</code > needed: ```rust let name = "World"; let count = 42; let code = ts_template! { console.log("Hello @{name}!"); console.log("Count: @{count}, doubled: @{count * 2}"); }; ``` **Generates:** ```typescript console.log("Hello World!"); console.log("Count: 42, doubled: 84"); ``` This also works with method calls and complex expressions: ```rust let field = "username"; let code = ts_template! { throw new Error("Invalid @{field.to_uppercase()}"); }; ``` <h2 id="backtick-templates"> Backtick Template Literals: `"'^...^'"` </h2> For JavaScript template literals (backtick strings), use the <code >'^...^'</code > syntax. This outputs actual backticks and passes through `${"${}"}` for JS interpolation: ```rust let tag_name = "div"; let code = ts_template! { const html = "'^<@{tag_name}>\${content}</@{tag_name}>^'"; }; ``` **Generates:** <CodeBlock code={"const html = `${content}`;"} lang="typescript" /> You can mix Rust `@&#123;&#125;` interpolation (evaluated at macro expansion time) with JS `${"${}"}` interpolation (evaluated at runtime): ```rust let class_name = "User"; let code = ts_template! { "'^Hello \${this.name}, you are a @{class_name}^'" }; ``` **Generates:** <CodeBlock code={"`Hello ${this.name}, you are a User`"} lang="typescript" /> <h2 id="conditionals"> Conditionals: `&#123;#if&#125;...&#123;/if&#125;` </h2> Basic conditional: ```rust let needs_validation = true; let code = ts_template! { function save() { {#if needs_validation} if (!this.isValid()) return false; {/if} return this.doSave(); } }; ``` ### If-Else ```rust let has_default = true; let code = ts_template! { {#if has_default} return defaultValue; {:else} throw new Error("No default"); {/if} }; ``` ### If-Else-If Chains ```rust let level = 2; let code = ts_template! { {#if level == 1} console.log("Level 1"); {:else if level == 2} console.log("Level 2"); {:else} console.log("Other level"); {/if} }; ``` <h2 id="pattern-matching"> Pattern Matching: `&#123;#if let&#125;` </h2> Use `if let` for pattern matching on `Option`, `Result`, or other Rust enums: ```rust let maybe_name: Option<&str> = Some("Alice"); let code = ts_template! { {#if let Some(name) = maybe_name} console.log("Hello, @{name}!"); {:else} console.log("Hello, anonymous!"); {/if} }; ``` **Generates:** ```typescript console.log("Hello, Alice!"); ``` This is useful when working with optional values from your IR: ```rust let code = ts_template! { {#if let Some(default_val) = field.default_value} this.@{field.name} = @{default_val}; {:else} this.@{field.name} = undefined; {/if} }; ``` <h2 id="match-expressions"> Match Expressions: `&#123;#match&#125;` </h2> Use `match` for exhaustive pattern matching: ```rust enum Visibility { Public, Private, Protected } let visibility = Visibility::Public; let code = ts_template! { {#match visibility} {:case Visibility::Public} public {:case Visibility::Private} private {:case Visibility::Protected} protected {/match} field: string; }; ``` **Generates:** ```typescript public field: string; ``` ### Match with Value Extraction ```rust let result: Result<i32, &str> = Ok(42); let code = ts_template! { const value = {#match result} {:case Ok(val)} @{val} {:case Err(msg)} throw new Error("@{msg}") {/match}; }; ``` ### Match with Wildcard ```rust let count = 5; let code = ts_template! { {#match count} {:case 0} console.log("none"); {:case 1} console.log("one"); {:case _} console.log("many"); {/match} }; ```

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/macroforge-ts/mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server