Skip to content

forge-weld-macro

The forge-weld-macro crate provides procedural macros for annotating Rust code with metadata used for TypeScript code generation.

Overview

The macros in this crate:

  1. Leave original code unchanged - No modifications to your Rust implementations
  2. Generate companion metadata - Create functions that return type information
  3. Register with inventory - Add metadata to forge-weld’s compile-time registry

Macros

#[weld_op]

Annotate deno_core ops for TypeScript binding generation:

use forge_weld_macro::weld_op;
#[weld_op(async)]
#[op2(async)]
pub async fn op_fs_read_text(
#[string] path: String,
) -> Result<String, FsError> {
// implementation
}

Attributes:

AttributeDescription
#[weld_op]Sync op
#[weld_op(async)]Async op
#[weld_op(ts_name = "customName")]Custom TypeScript function name

Generated TypeScript:

export function readTextFile(path: string): Promise<string>;

#[weld_struct]

Annotate structs for TypeScript interface generation:

use forge_weld_macro::weld_struct;
#[weld_struct]
#[derive(Serialize, Deserialize)]
pub struct FileStat {
pub is_file: bool,
pub is_directory: bool,
pub size: u64,
pub modified: Option<u64>,
}

Attributes:

AttributeDescription
#[weld_struct]Basic struct
#[weld_struct(ts_name = "CustomName")]Custom TypeScript interface name

Generated TypeScript:

export interface FileStat {
is_file: boolean;
is_directory: boolean;
size: number;
modified?: number;
}

#[weld_enum]

Annotate enums for TypeScript union type generation:

use forge_weld_macro::weld_enum;
#[weld_enum]
#[derive(Serialize, Deserialize)]
pub enum WatchEventKind {
Create,
Modify,
Remove,
}

Generated TypeScript:

export type WatchEventKind = "Create" | "Modify" | "Remove";

How It Works

When you use #[weld_op]:

  1. The macro parses the function signature
  2. Generates a companion function returning OpSymbol
  3. Registers the symbol in WELD_OPS distributed slice
// Your code
#[weld_op(async)]
#[op2(async)]
pub async fn op_fs_read_text(path: String) -> Result<String, FsError> { ... }
// Generated (simplified)
#[linkme::distributed_slice(forge_weld::WELD_OPS)]
fn __weld_op_fs_read_text() -> OpSymbol {
OpSymbol {
name: "op_fs_read_text",
is_async: true,
params: vec![OpParam { name: "path", ty: WeldType::String }],
return_type: WeldType::Promise(Box::new(WeldType::String)),
}
}

Usage Example

Complete example for a filesystem extension:

use forge_weld_macro::{weld_op, weld_struct, weld_enum};
use serde::{Deserialize, Serialize};
// Define types
#[weld_struct]
#[derive(Serialize, Deserialize)]
pub struct FileInfo {
pub path: String,
pub size: u64,
}
#[weld_enum]
#[derive(Serialize, Deserialize)]
pub enum FileType {
File,
Directory,
Symlink,
}
// Define ops
#[weld_op(async)]
#[op2(async)]
pub async fn op_fs_stat(
#[string] path: String,
) -> Result<FileInfo, FsError> {
// implementation
}
#[weld_op]
#[op2]
pub fn op_fs_exists(
#[string] path: String,
) -> bool {
// implementation
}

Type Parser

The type_parser.rs module provides strict Rust→TypeScript type conversion. It panics on unsupported types to ensure no unknown types slip through to generated TypeScript.

Supported types:

  • Primitives: u8-u64, i8-i64, f32, f64, bool, String, char, ()
  • Containers: Option<T>, Vec<T>, Result<T, E>, HashMap<K, V>, BTreeMap<K, V>
  • Sets: HashSet<T>, BTreeSet<T>
  • Smart pointers: Box<T>, Arc<T>, Rc<T>, RefCell<T>, Mutex<T>, RwLock<T>
  • References: &T, &mut T
  • Tuples: (A, B, C)
  • Arrays/Slices: [T; N], [T]
  • Special: serde_json::ValueJsonValue, OpState
  • Custom types: Treated as struct references

Unsupported types (will panic):

  • Bare function types (fn(A) -> B)
  • impl Trait types
  • Trait objects (dyn Trait)
  • Inferred types (_)
  • Macro types

File Structure

crates/forge-weld-macro/
├── src/
│ ├── lib.rs # Macro entry points
│ ├── weld_op.rs # #[weld_op] implementation
│ ├── weld_struct.rs # #[weld_struct] and #[weld_enum] implementation
│ └── type_parser.rs # Rust→WeldType conversion with strict validation
└── Cargo.toml

Dependencies

DependencyPurpose
synRust syntax parsing
quoteToken generation
proc-macro2Proc macro utilities