UNPKG

@macroforge/mcp-server

Version:

MCP server for Macroforge documentation and code analysis

203 lines (155 loc) • 9.99 kB
# Built-in Macros Macroforge comes with built-in derive macros that cover the most common code generation needs. All macros work with classes, interfaces, enums, and type aliases. ## Overview | Macro | Generates | Description | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- | | [`Debug`](../docs/builtin-macros/debug) | `static toString(value: T): string` | Human-readable string representation | | [`Clone`](../docs/builtin-macros/clone) | `static clone(value: T): T` | Creates a deep copy of the object | | [`Default`](../docs/builtin-macros/default) | `static defaultValue(): T` | Creates an instance with default values | | [`Hash`](../docs/builtin-macros/hash) | `static hashCode(value: T): number` | Generates a hash code for the object | | [`PartialEq`](../docs/builtin-macros/partial-eq) | `static equals(a: T, b: T): boolean` | Value equality comparison | | [`Eq`](../docs/builtin-macros/eq) | None | Marks equality as total; requires `PartialEq` | | [`Ord`](../docs/builtin-macros/ord) | `static compare(a: T, b: T): number` | Total ordering comparison (-1, 0, 1); requires `Eq` and `PartialOrd` | | [`PartialOrd`](../docs/builtin-macros/partial-ord) | `static partialCompare(a: T, b: T): number &#124; null` | Partial ordering comparison; requires `PartialEq` | | [`Encode`](../docs/builtin-macros/encode) | `static encode(value: T, keepMetadata?: boolean): string` | JSON encoding with type handling | | [`Decode`](../docs/builtin-macros/decode) | `static decode(input, opts?): &lbrace; success: true; value: T &rbrace; &#124; &lbrace; success: false; errors &rbrace;` | JSON decoding with validation | ## Type-Position Macros One built-in macro is written where a type goes rather than in `@derive`: | Macro | Expands To | Description | | ----------------------------------------------- | ---------------------------------------------- | -------------------------------------------------- | | [`$Newtype<T>`](../docs/builtin-macros/newtype) | `T & &lbrace; readonly [brand]: true &rbrace;` | Nominal brand backed by a per-site `unique symbol` | ## Using Built-in Macros Built-in macros don't require imports. Just use them with `@derive`: TypeScript ``` /** @derive(Debug, Clone, PartialEq) */ class User {   name: string;   age: number;   constructor(name: string, age: number) {     this.name = name;     this.age = age;   } } ``` ## Interface Support All built-in macros work with interfaces. Interfaces have no class to attach statics to, so they get standalone functions named `&lbrace;typeName&rbrace;&lbrace;Operation&rbrace;` taking the value as the first parameter. When `generateConvenienceConst` is enabled (the default), a grouping `const` is also emitted so you can call them by short name: TypeScript ``` /** @derive(Debug, Clone, PartialEq) */ interface Point {   x: number;   y: number; } // Generated standalone functions: // export function pointToString(value: Point): string { ... } // export function pointClone(value: Point): Point { ... } // export function pointEquals(a: Point, b: Point): boolean { ... } // export function pointHashCode(value: Point): number { ... } // Plus a grouping const (generateConvenienceConst, on by default): // export const Point = { //   toString: pointToString, //   clone: pointClone, //   equals: pointEquals, //   hashCode: pointHashCode, // } as const; const point: Point = { x: 10, y: 20 }; console.log(pointToString(point));      // "Point { x: 10, y: 20 }" const copy = pointClone(point);         // { x: 10, y: 20 } console.log(pointEquals(point, copy));  // true // …or via the grouping const console.log(Point.toString(point)); ``` ## Enum Support All built-in macros work with enums. For enums, methods are generated as functions in a namespace with the same name: TypeScript ``` /** @derive(Debug, Clone, PartialEq, Encode, Decode) */ enum Status {   Active = "active",   Inactive = "inactive",   Pending = "pending", } // Generated standalone functions: // export function statusToString(value: Status): string { ... } // export function statusClone(value: Status): Status { ... } // export function statusEquals(a: Status, b: Status): boolean { ... } // export function statusHashCode(value: Status): number { ... } // export function statusEncode(value: Status): string { ... } // export function statusDecode(input: unknown): Status { ... } // Enums use namespace merging for the convenience names: // namespace Status { //   export const toString = statusToString; //   export const encode = statusEncode; // } console.log(statusToString(Status.Active));                // "Status.Active" console.log(statusEquals(Status.Active, Status.Active));   // true const json = statusEncode(Status.Pending);              // "pending" // Note: enum decode throws on invalid input rather than // returning a success/errors union. const parsed = statusDecode("active");                // Status.Active ``` ## Type Alias Support All built-in macros work with type aliases. Object type aliases get field-aware standalone functions, plus the optional grouping `const`: TypeScript ``` /** @derive(Debug, Clone, PartialEq, Encode, Decode) */ type Point = {   x: number;   y: number; }; // Generated standalone functions: // export function pointToString(value: Point): string { ... } // export function pointClone(value: Point): Point { ... } // export function pointEquals(a: Point, b: Point): boolean { ... } // export function pointHashCode(value: Point): number { ... } // export function pointEncode(value: Point, keepMetadata?: boolean): string { ... } // export function pointDecode(input: unknown, opts?): { success: true; value: Point } //                                                        | { success: false; errors } { ... } const point: Point = { x: 10, y: 20 }; console.log(pointToString(point));      // "Point { x: 10, y: 20 }" const copy = pointClone(point);         // { x: 10, y: 20 } console.log(pointEquals(point, copy));  // true ``` Union type aliases also work, using JSON-based implementations: TypeScript ``` /** @derive(Debug, PartialEq) */ type ApiStatus = "loading" | "success" | "error"; const status: ApiStatus = "success"; console.log(ApiStatus.toString(status)); // "ApiStatus(\\"success\\")" console.log(ApiStatus.equals("success", "success")); // true ``` ## Combining Macros All macros can be used together. They don't conflict and each generates independent methods: TypeScript ``` const user = new User("Alice", 30); // Debug console.log(User.toString(user)); // "User { name: Alice, age: 30 }" // Clone const copy = User.clone(user); console.log(copy.name); // "Alice" // PartialEq console.log(User.equals(user, copy)); // true ``` ## Detailed Documentation Each macro has its own options and behaviors: - [**Debug**](../docs/builtin-macros/debug) - Customizable field renaming and skipping - [**Clone**](../docs/builtin-macros/clone) - Deep copying for all field types - [**Default**](../docs/builtin-macros/default) - Default value generation with field attributes - [**Hash**](../docs/builtin-macros/hash) - Hash code generation for use in maps and sets - [**PartialEq**](../docs/builtin-macros/partial-eq) - Value-based equality comparison - [**Eq**](../docs/builtin-macros/eq) - Marks equality as total, as Rust's `Eq` - [**Ord**](../docs/builtin-macros/ord) - Total ordering for sorting - [**PartialOrd**](../docs/builtin-macros/partial-ord) - Partial ordering comparison - [**Encode**](../docs/builtin-macros/encode) - JSON encoding with endec-style options - [**Decode**](../docs/builtin-macros/decode) - JSON decoding with validation - [**$Newtype**](../docs/builtin-macros/newtype) - Nominal brands, constructed through `Decode`