@macroforge/mcp-server 0.1.32 → 0.1.34
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 +68 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +46 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/docs-loader.d.ts +133 -5
- package/dist/tools/docs-loader.d.ts.map +1 -1
- package/dist/tools/docs-loader.js +131 -15
- package/dist/tools/docs-loader.js.map +1 -1
- package/dist/tools/index.d.ts +48 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +163 -14
- package/dist/tools/index.js.map +1 -1
- package/docs/api/api-overview.md +24 -46
- package/docs/api/expand-sync.md +24 -51
- package/docs/api/native-plugin.md +24 -56
- package/docs/api/position-mapper.md +34 -76
- package/docs/api/transform-sync.md +27 -59
- package/docs/builtin-macros/clone.md +150 -68
- package/docs/builtin-macros/debug.md +216 -81
- package/docs/builtin-macros/default.md +234 -91
- package/docs/builtin-macros/deserialize.md +891 -166
- package/docs/builtin-macros/hash.md +238 -82
- package/docs/builtin-macros/macros-overview.md +42 -103
- package/docs/builtin-macros/ord.md +205 -92
- package/docs/builtin-macros/partial-eq.md +178 -97
- package/docs/builtin-macros/partial-ord.md +209 -98
- package/docs/builtin-macros/serialize.md +326 -137
- package/docs/concepts/architecture.md +40 -99
- package/docs/concepts/derive-system.md +132 -125
- package/docs/concepts/how-macros-work.md +52 -84
- package/docs/custom-macros/custom-overview.md +17 -39
- package/docs/custom-macros/rust-setup.md +22 -55
- package/docs/custom-macros/ts-macro-derive.md +43 -107
- package/docs/custom-macros/ts-quote.md +177 -507
- package/docs/getting-started/first-macro.md +108 -33
- package/docs/getting-started/installation.md +32 -73
- package/docs/integration/cli.md +70 -156
- package/docs/integration/configuration.md +32 -75
- package/docs/integration/integration-overview.md +16 -55
- package/docs/integration/mcp-server.md +30 -69
- package/docs/integration/svelte-preprocessor.md +60 -83
- package/docs/integration/typescript-plugin.md +32 -74
- package/docs/integration/vite-plugin.md +30 -79
- package/docs/language-servers/ls-overview.md +22 -46
- package/docs/language-servers/svelte.md +30 -69
- package/docs/language-servers/zed.md +34 -72
- package/docs/roadmap/roadmap.md +54 -130
- package/docs/sections.json +3 -262
- package/package.json +2 -2
|
@@ -1,12 +1,54 @@
|
|
|
1
1
|
# Hash
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
*The `Hash` macro generates a `hashCode()` method for computing numeric hash codes. This is analogous to Rust's `Hash` trait and Java's `hashCode()` method, enabling objects to be used as keys in hash-based collections.*
|
|
3
|
+
## Basic Usage
|
|
4
|
+
**Before:**
|
|
5
|
+
```
|
|
6
|
+
/** @derive(Hash) */
|
|
7
|
+
class Point {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
|
|
11
|
+
constructor(x: number, y: number) {
|
|
12
|
+
this.x = x;
|
|
13
|
+
this.y = y;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
```
|
|
17
|
+
**After:**
|
|
18
|
+
```
|
|
19
|
+
class Point {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
|
|
23
|
+
constructor(x: number, y: number) {
|
|
24
|
+
this.x = x;
|
|
25
|
+
this.y = y;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
hashCode(): number {
|
|
29
|
+
let hash = 17;
|
|
30
|
+
hash =
|
|
31
|
+
(hash * 31 +
|
|
32
|
+
(Number.isInteger(this.x)
|
|
33
|
+
? this.x | 0
|
|
34
|
+
: this.x
|
|
35
|
+
.toString()
|
|
36
|
+
.split('')
|
|
37
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
38
|
+
0;
|
|
39
|
+
hash =
|
|
40
|
+
(hash * 31 +
|
|
41
|
+
(Number.isInteger(this.y)
|
|
42
|
+
? this.y | 0
|
|
43
|
+
: this.y
|
|
44
|
+
.toString()
|
|
45
|
+
.split('')
|
|
46
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
47
|
+
0;
|
|
48
|
+
return hash;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
``` ```
|
|
10
52
|
const p1 = new Point(10, 20);
|
|
11
53
|
const p2 = new Point(10, 20);
|
|
12
54
|
const p3 = new Point(5, 5);
|
|
@@ -14,52 +56,80 @@ const p3 = new Point(5, 5);
|
|
|
14
56
|
console.log(p1.hashCode()); // Same hash
|
|
15
57
|
console.log(p2.hashCode()); // Same hash (equal values = equal hash)
|
|
16
58
|
console.log(p3.hashCode()); // Different hash
|
|
59
|
+
``` ## Hash Algorithm
|
|
60
|
+
The generated hash function uses the following algorithm for different types:
|
|
61
|
+
- `number` → Integers use bitwise OR (`| 0`), floats are stringified and hashed
|
|
62
|
+
- `string` → Character-by-character hash: `(h * 31 + charCode) | 0`
|
|
63
|
+
- `boolean` → `1231` for true, `1237` for false (Java convention)
|
|
64
|
+
- `bigint` → Converted to string and hashed character-by-character
|
|
65
|
+
- `Date` → Uses `getTime() | 0` for timestamp hash
|
|
66
|
+
- `Array` → Combines element hashes with `h * 31 + elementHash`
|
|
67
|
+
- `Map/Set` → Combines all entry hashes
|
|
68
|
+
- `Object` → Calls `hashCode()` if available, otherwise JSON stringifies and hashes
|
|
69
|
+
- `null` → Returns 0
|
|
70
|
+
- `undefined` → Returns 1
|
|
71
|
+
## Field Options
|
|
72
|
+
### @hash(skip)
|
|
73
|
+
Use `@hash(skip)` to exclude a field from hash computation:
|
|
74
|
+
**Before:**
|
|
17
75
|
```
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
/** @derive(Hash) */
|
|
77
|
+
class User {
|
|
78
|
+
id: number;
|
|
79
|
+
name: string;
|
|
80
|
+
|
|
81
|
+
/** @hash(skip) */
|
|
82
|
+
lastLogin: Date;
|
|
83
|
+
|
|
84
|
+
constructor(id: number, name: string, lastLogin: Date) {
|
|
85
|
+
this.id = id;
|
|
86
|
+
this.name = name;
|
|
87
|
+
this.lastLogin = lastLogin;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
**After:**
|
|
92
|
+
```
|
|
93
|
+
class User {
|
|
94
|
+
id: number;
|
|
95
|
+
name: string;
|
|
96
|
+
|
|
97
|
+
lastLogin: Date;
|
|
98
|
+
|
|
99
|
+
constructor(id: number, name: string, lastLogin: Date) {
|
|
100
|
+
this.id = id;
|
|
101
|
+
this.name = name;
|
|
102
|
+
this.lastLogin = lastLogin;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
hashCode(): number {
|
|
106
|
+
let hash = 17;
|
|
107
|
+
hash =
|
|
108
|
+
(hash * 31 +
|
|
109
|
+
(Number.isInteger(this.id)
|
|
110
|
+
? this.id | 0
|
|
111
|
+
: this.id
|
|
112
|
+
.toString()
|
|
113
|
+
.split('')
|
|
114
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
115
|
+
0;
|
|
116
|
+
hash =
|
|
117
|
+
(hash * 31 +
|
|
118
|
+
(this.name ?? '').split('').reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0)) |
|
|
119
|
+
0;
|
|
120
|
+
return hash;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
``` ```
|
|
52
124
|
const user1 = new User(1, "Alice", new Date("2024-01-01"));
|
|
53
125
|
const user2 = new User(1, "Alice", new Date("2024-12-01"));
|
|
54
126
|
|
|
55
127
|
console.log(user1.hashCode() === user2.hashCode()); // true (lastLogin is skipped)
|
|
128
|
+
``` ## Use with PartialEq
|
|
129
|
+
Hash is often used together with PartialEq. Objects that are equal should have the same hash code:
|
|
130
|
+
**Source:**
|
|
56
131
|
```
|
|
57
|
-
|
|
58
|
-
## Use with PartialEq
|
|
59
|
-
|
|
60
|
-
Hash is often used together with PartialEq. Objects that are equal should have the same hash code:
|
|
61
|
-
|
|
62
|
-
<InteractiveMacro code={`/** @derive(Hash, PartialEq) */
|
|
132
|
+
/** @derive(Hash, PartialEq) */
|
|
63
133
|
class Product {
|
|
64
134
|
sku: string;
|
|
65
135
|
name: string;
|
|
@@ -68,56 +138,142 @@ class Product {
|
|
|
68
138
|
this.sku = sku;
|
|
69
139
|
this.name = name;
|
|
70
140
|
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
141
|
+
}
|
|
142
|
+
``` ```
|
|
74
143
|
const p1 = new Product("ABC123", "Widget");
|
|
75
144
|
const p2 = new Product("ABC123", "Widget");
|
|
76
145
|
|
|
77
146
|
// Equal objects have equal hash codes
|
|
78
147
|
console.log(p1.equals(p2)); // true
|
|
79
148
|
console.log(p1.hashCode() === p2.hashCode()); // true
|
|
149
|
+
``` ## Interface Support
|
|
150
|
+
Hash also works with interfaces. For interfaces, a namespace is generated with a `hashCode` function:
|
|
151
|
+
**Before:**
|
|
80
152
|
```
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
```
|
|
153
|
+
/** @derive(Hash) */
|
|
154
|
+
interface Point {
|
|
155
|
+
x: number;
|
|
156
|
+
y: number;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
**After:**
|
|
160
|
+
```
|
|
161
|
+
interface Point {
|
|
162
|
+
x: number;
|
|
163
|
+
y: number;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export namespace Point {
|
|
167
|
+
export function hashCode(self: Point): number {
|
|
168
|
+
let hash = 17;
|
|
169
|
+
hash =
|
|
170
|
+
(hash * 31 +
|
|
171
|
+
(Number.isInteger(self.x)
|
|
172
|
+
? self.x | 0
|
|
173
|
+
: self.x
|
|
174
|
+
.toString()
|
|
175
|
+
.split('')
|
|
176
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
177
|
+
0;
|
|
178
|
+
hash =
|
|
179
|
+
(hash * 31 +
|
|
180
|
+
(Number.isInteger(self.y)
|
|
181
|
+
? self.y | 0
|
|
182
|
+
: self.y
|
|
183
|
+
.toString()
|
|
184
|
+
.split('')
|
|
185
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
186
|
+
0;
|
|
187
|
+
return hash;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
``` ```
|
|
89
191
|
const p: Point = { x: 10, y: 20 };
|
|
90
192
|
console.log(Point.hashCode(p)); // numeric hash value
|
|
193
|
+
``` ## Enum Support
|
|
194
|
+
Hash works with enums. For string enums, it hashes the string value; for numeric enums, it uses the numeric value directly:
|
|
195
|
+
**Before:**
|
|
91
196
|
```
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
197
|
+
/** @derive(Hash) */
|
|
198
|
+
enum Status {
|
|
199
|
+
Active = 'active',
|
|
200
|
+
Inactive = 'inactive',
|
|
201
|
+
Pending = 'pending'
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
**After:**
|
|
205
|
+
```
|
|
206
|
+
enum Status {
|
|
207
|
+
Active = 'active',
|
|
208
|
+
Inactive = 'inactive',
|
|
209
|
+
Pending = 'pending'
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export namespace Status {
|
|
213
|
+
export function hashCode(value: Status): number {
|
|
214
|
+
if (typeof value === 'string') {
|
|
215
|
+
let hash = 0;
|
|
216
|
+
for (let i = 0; i < value.length; i++) {
|
|
217
|
+
hash = (hash * 31 + value.charCodeAt(i)) | 0;
|
|
218
|
+
}
|
|
219
|
+
return hash;
|
|
220
|
+
}
|
|
221
|
+
return value as number;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
``` ```
|
|
100
225
|
console.log(Status.hashCode(Status.Active)); // consistent hash
|
|
101
226
|
console.log(Status.hashCode(Status.Inactive)); // different hash
|
|
227
|
+
``` ## Type Alias Support
|
|
228
|
+
Hash works with type aliases. For object types, it hashes each field:
|
|
229
|
+
**Before:**
|
|
102
230
|
```
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
```
|
|
231
|
+
/** @derive(Hash) */
|
|
232
|
+
type Coordinates = {
|
|
233
|
+
lat: number;
|
|
234
|
+
lng: number;
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
**After:**
|
|
238
|
+
```
|
|
239
|
+
type Coordinates = {
|
|
240
|
+
lat: number;
|
|
241
|
+
lng: number;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
export namespace Coordinates {
|
|
245
|
+
export function hashCode(value: Coordinates): number {
|
|
246
|
+
let hash = 17;
|
|
247
|
+
hash =
|
|
248
|
+
(hash * 31 +
|
|
249
|
+
(Number.isInteger(value.lat)
|
|
250
|
+
? value.lat | 0
|
|
251
|
+
: value.lat
|
|
252
|
+
.toString()
|
|
253
|
+
.split('')
|
|
254
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
255
|
+
0;
|
|
256
|
+
hash =
|
|
257
|
+
(hash * 31 +
|
|
258
|
+
(Number.isInteger(value.lng)
|
|
259
|
+
? value.lng | 0
|
|
260
|
+
: value.lng
|
|
261
|
+
.toString()
|
|
262
|
+
.split('')
|
|
263
|
+
.reduce((h, c) => (h * 31 + c.charCodeAt(0)) | 0, 0))) |
|
|
264
|
+
0;
|
|
265
|
+
return hash;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
``` ```
|
|
111
269
|
const loc: Coordinates = { lat: 40.7128, lng: -74.0060 };
|
|
112
270
|
console.log(Coordinates.hashCode(loc));
|
|
271
|
+
``` For union types, it uses JSON stringification as a fallback:
|
|
272
|
+
**Source:**
|
|
113
273
|
```
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<InteractiveMacro code={`/** @derive(Hash) */
|
|
118
|
-
type Result = "success" | "error" | "pending";`} />
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
274
|
+
/** @derive(Hash) */
|
|
275
|
+
type Result = "success" | "error" | "pending";
|
|
276
|
+
``` ```
|
|
121
277
|
console.log(Result.hashCode("success")); // hash of "success" string
|
|
122
278
|
console.log(Result.hashCode("error")); // hash of "error" string
|
|
123
279
|
```
|
|
@@ -1,50 +1,20 @@
|
|
|
1
1
|
# Built-in Macros
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
| [`
|
|
8
|
-
| `
|
|
9
|
-
|
|
|
10
|
-
|
|
11
|
-
| [`
|
|
12
|
-
| `
|
|
13
|
-
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
| [`Hash`]({base}/docs/builtin-macros/hash)
|
|
20
|
-
| `hashCode(): number`
|
|
21
|
-
| Generates a hash code for the object
|
|
22
|
-
|
|
23
|
-
| [`PartialEq`]({base}/docs/builtin-macros/partial-eq)
|
|
24
|
-
| `equals(other: T): boolean`
|
|
25
|
-
| Value equality comparison
|
|
26
|
-
|
|
27
|
-
| [`Ord`]({base}/docs/builtin-macros/ord)
|
|
28
|
-
| `compare(other: T): number`
|
|
29
|
-
| Total ordering comparison (-1, 0, 1)
|
|
30
|
-
|
|
31
|
-
| [`PartialOrd`]({base}/docs/builtin-macros/partial-ord)
|
|
32
|
-
| `partialCompare(other: T): number | null`
|
|
33
|
-
| Partial ordering comparison
|
|
34
|
-
|
|
35
|
-
| [`Serialize`]({base}/docs/builtin-macros/serialize)
|
|
36
|
-
| `toJSON(): Record<string, unknown>`
|
|
37
|
-
| JSON serialization with type handling
|
|
38
|
-
|
|
39
|
-
| [`Deserialize`]({base}/docs/builtin-macros/deserialize)
|
|
40
|
-
| `static fromJSON(data: unknown): T`
|
|
41
|
-
| JSON deserialization with validation
|
|
42
|
-
|
|
43
|
-
## Using Built-in Macros
|
|
44
|
-
|
|
45
|
-
Built-in macros don't require imports. Just use them with `@derive`:
|
|
46
|
-
|
|
47
|
-
```typescript
|
|
2
|
+
*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.*
|
|
3
|
+
## Overview
|
|
4
|
+
| Macro | Generates | Description |
|
|
5
|
+
| --- | --- | --- |
|
|
6
|
+
| [`Debug`](../docs/builtin-macros/debug) | `toString(): string` | Human-readable string representation |
|
|
7
|
+
| [`Clone`](../docs/builtin-macros/clone) | `clone(): T` | Creates a deep copy of the object |
|
|
8
|
+
| [`Default`](../docs/builtin-macros/default) | `static default(): T` | Creates an instance with default values |
|
|
9
|
+
| [`Hash`](../docs/builtin-macros/hash) | `hashCode(): number` | Generates a hash code for the object |
|
|
10
|
+
| [`PartialEq`](../docs/builtin-macros/partial-eq) | `equals(other: T): boolean` | Value equality comparison |
|
|
11
|
+
| [`Ord`](../docs/builtin-macros/ord) | `compare(other: T): number` | Total ordering comparison (-1, 0, 1) |
|
|
12
|
+
| [`PartialOrd`](../docs/builtin-macros/partial-ord) | `partialCompare(other: T): number | null` | Partial ordering comparison |
|
|
13
|
+
| [`Serialize`](../docs/builtin-macros/serialize) | `toJSON(): Record<string, unknown>` | JSON serialization with type handling |
|
|
14
|
+
| [`Deserialize`](../docs/builtin-macros/deserialize) | `static fromJSON(data: unknown): T` | JSON deserialization with validation |
|
|
15
|
+
## Using Built-in Macros
|
|
16
|
+
Built-in macros don't require imports. Just use them with `@derive`:
|
|
17
|
+
```
|
|
48
18
|
/** @derive(Debug, Clone, PartialEq) */
|
|
49
19
|
class User {
|
|
50
20
|
name: string;
|
|
@@ -55,13 +25,9 @@ class User {
|
|
|
55
25
|
this.age = age;
|
|
56
26
|
}
|
|
57
27
|
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
All built-in macros work with interfaces. For interfaces, methods are generated as functions in a namespace with the same name, using `self` as the first parameter:
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
28
|
+
``` ## Interface Support
|
|
29
|
+
All built-in macros work with interfaces. For interfaces, methods are generated as functions in a namespace with the same name, using `self` as the first parameter:
|
|
30
|
+
```
|
|
65
31
|
/** @derive(Debug, Clone, PartialEq) */
|
|
66
32
|
interface Point {
|
|
67
33
|
x: number;
|
|
@@ -82,13 +48,9 @@ const point: Point = { x: 10, y: 20 };
|
|
|
82
48
|
console.log(Point.toString(point)); // "Point { x: 10, y: 20 }"
|
|
83
49
|
const copy = Point.clone(point); // { x: 10, y: 20 }
|
|
84
50
|
console.log(Point.equals(point, copy)); // true
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
All built-in macros work with enums. For enums, methods are generated as functions in a namespace with the same name:
|
|
90
|
-
|
|
91
|
-
```typescript
|
|
51
|
+
``` ## Enum Support
|
|
52
|
+
All built-in macros work with enums. For enums, methods are generated as functions in a namespace with the same name:
|
|
53
|
+
```
|
|
92
54
|
/** @derive(Debug, Clone, PartialEq, Serialize, Deserialize) */
|
|
93
55
|
enum Status {
|
|
94
56
|
Active = "active",
|
|
@@ -111,13 +73,9 @@ console.log(Status.toString(Status.Active)); // "Status.Active"
|
|
|
111
73
|
console.log(Status.equals(Status.Active, Status.Active)); // true
|
|
112
74
|
const json = Status.toJSON(Status.Pending); // "pending"
|
|
113
75
|
const parsed = Status.fromJSON("active"); // Status.Active
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
All built-in macros work with type aliases. For object type aliases, field-aware methods are generated in a namespace:
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
76
|
+
``` ## Type Alias Support
|
|
77
|
+
All built-in macros work with type aliases. For object type aliases, field-aware methods are generated in a namespace:
|
|
78
|
+
```
|
|
121
79
|
/** @derive(Debug, Clone, PartialEq, Serialize, Deserialize) */
|
|
122
80
|
type Point = {
|
|
123
81
|
x: number;
|
|
@@ -138,24 +96,17 @@ const point: Point = { x: 10, y: 20 };
|
|
|
138
96
|
console.log(Point.toString(point)); // "Point { x: 10, y: 20 }"
|
|
139
97
|
const copy = Point.clone(point); // { x: 10, y: 20 }
|
|
140
98
|
console.log(Point.equals(point, copy)); // true
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Union type aliases also work, using JSON-based implementations:
|
|
144
|
-
|
|
145
|
-
```typescript
|
|
99
|
+
``` Union type aliases also work, using JSON-based implementations:
|
|
100
|
+
```
|
|
146
101
|
/** @derive(Debug, PartialEq) */
|
|
147
102
|
type ApiStatus = "loading" | "success" | "error";
|
|
148
103
|
|
|
149
104
|
const status: ApiStatus = "success";
|
|
150
|
-
console.log(ApiStatus.toString(status)); // "ApiStatus(
|
|
105
|
+
console.log(ApiStatus.toString(status)); // "ApiStatus(\"success\")"
|
|
151
106
|
console.log(ApiStatus.equals("success", "success")); // true
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
All macros can be used together. They don't conflict and each generates independent methods:
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
107
|
+
``` ## Combining Macros
|
|
108
|
+
All macros can be used together. They don't conflict and each generates independent methods:
|
|
109
|
+
```
|
|
159
110
|
const user = new User("Alice", 30);
|
|
160
111
|
|
|
161
112
|
// Debug
|
|
@@ -168,26 +119,14 @@ console.log(copy.name); // "Alice"
|
|
|
168
119
|
|
|
169
120
|
// Eq
|
|
170
121
|
console.log(user.equals(copy)); // true
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
- [**
|
|
178
|
-
|
|
179
|
-
- [**
|
|
180
|
-
|
|
181
|
-
- [**
|
|
182
|
-
|
|
183
|
-
- [**Hash**]({base}/docs/builtin-macros/hash) - Hash code generation for use in maps and sets
|
|
184
|
-
|
|
185
|
-
- [**PartialEq**]({base}/docs/builtin-macros/partial-eq) - Value-based equality comparison
|
|
186
|
-
|
|
187
|
-
- [**Ord**]({base}/docs/builtin-macros/ord) - Total ordering for sorting
|
|
188
|
-
|
|
189
|
-
- [**PartialOrd**]({base}/docs/builtin-macros/partial-ord) - Partial ordering comparison
|
|
190
|
-
|
|
191
|
-
- [**Serialize**]({base}/docs/builtin-macros/serialize) - JSON serialization with serde-style options
|
|
192
|
-
|
|
193
|
-
- [**Deserialize**]({base}/docs/builtin-macros/deserialize) - JSON deserialization with validation
|
|
122
|
+
``` ## Detailed Documentation
|
|
123
|
+
Each macro has its own options and behaviors:
|
|
124
|
+
- [**Debug**](../docs/builtin-macros/debug) - Customizable field renaming and skipping
|
|
125
|
+
- [**Clone**](../docs/builtin-macros/clone) - Deep copying for all field types
|
|
126
|
+
- [**Default**](../docs/builtin-macros/default) - Default value generation with field attributes
|
|
127
|
+
- [**Hash**](../docs/builtin-macros/hash) - Hash code generation for use in maps and sets
|
|
128
|
+
- [**PartialEq**](../docs/builtin-macros/partial-eq) - Value-based equality comparison
|
|
129
|
+
- [**Ord**](../docs/builtin-macros/ord) - Total ordering for sorting
|
|
130
|
+
- [**PartialOrd**](../docs/builtin-macros/partial-ord) - Partial ordering comparison
|
|
131
|
+
- [**Serialize**](../docs/builtin-macros/serialize) - JSON serialization with serde-style options
|
|
132
|
+
- [**Deserialize**](../docs/builtin-macros/deserialize) - JSON deserialization with validation
|