@macroforge/mcp-server 0.1.33 → 0.1.35
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 +45 -104
- package/docs/builtin-macros/debug.md +33 -104
- package/docs/builtin-macros/default.md +78 -114
- package/docs/builtin-macros/deserialize.md +93 -273
- package/docs/builtin-macros/hash.md +58 -100
- package/docs/builtin-macros/macros-overview.md +42 -103
- package/docs/builtin-macros/ord.md +65 -133
- package/docs/builtin-macros/partial-eq.md +53 -179
- package/docs/builtin-macros/partial-ord.md +67 -159
- package/docs/builtin-macros/serialize.md +64 -194
- package/docs/concepts/architecture.md +40 -99
- package/docs/concepts/derive-system.md +129 -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,204 +1,78 @@
|
|
|
1
1
|
# PartialEq
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `PartialEq` macro generates an `equals()` method for field-by-field
|
|
4
|
+
structural equality comparison. This is analogous to Rust's `PartialEq` trait,
|
|
5
|
+
enabling value-based equality semantics instead of reference equality.
|
|
4
6
|
|
|
5
|
-
##
|
|
7
|
+
## Generated Output
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
| Type | Generated Code | Description |
|
|
10
|
+
|------|----------------|-------------|
|
|
11
|
+
| Class | `equals(other: unknown): boolean` | Instance method with instanceof check |
|
|
12
|
+
| Enum | `equalsEnumName(a: EnumName, b: EnumName): boolean` | Standalone function using strict equality |
|
|
13
|
+
| Interface | `equalsInterfaceName(a: InterfaceName, b: InterfaceName): boolean` | Standalone function comparing fields |
|
|
14
|
+
| Type Alias | `equalsTypeName(a: TypeName, b: TypeName): boolean` | Standalone function with type-appropriate comparison |
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
const p1 = new Point(10, 20);
|
|
11
|
-
const p2 = new Point(10, 20);
|
|
12
|
-
const p3 = new Point(5, 5);
|
|
13
|
-
|
|
14
|
-
console.log(p1.equals(p2)); // true (same values)
|
|
15
|
-
console.log(p1.equals(p3)); // false (different values)
|
|
16
|
-
console.log(p1 === p2); // false (different references)
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## How It Works
|
|
16
|
+
## Configuration
|
|
20
17
|
|
|
21
|
-
The
|
|
18
|
+
The `functionNamingStyle` option in `macroforge.json` controls naming:
|
|
19
|
+
- `"suffix"` (default): Suffixes with type name (e.g., `equalsMyType`)
|
|
20
|
+
- `"prefix"`: Prefixes with type name (e.g., `myTypeEquals`)
|
|
21
|
+
- `"generic"`: Uses TypeScript generics (e.g., `equals<T extends MyType>`)
|
|
22
|
+
- `"namespace"`: Legacy namespace wrapping
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
## Comparison Strategy
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
The generated equality check:
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
1. **Identity check**: `this === other` returns true immediately
|
|
29
|
+
2. **Type check**: For classes, uses `instanceof`; returns false if wrong type
|
|
30
|
+
3. **Field comparison**: Compares each non-skipped field
|
|
28
31
|
|
|
29
|
-
-
|
|
32
|
+
## Type-Specific Comparisons
|
|
30
33
|
|
|
31
|
-
|
|
34
|
+
| Type | Comparison Method |
|
|
35
|
+
|------|-------------------|
|
|
36
|
+
| Primitives | Strict equality (`===`) |
|
|
37
|
+
| Arrays | Length + element-by-element (recursive) |
|
|
38
|
+
| `Date` | `getTime()` comparison |
|
|
39
|
+
| `Map` | Size + entry-by-entry comparison |
|
|
40
|
+
| `Set` | Size + membership check |
|
|
41
|
+
| Objects | Calls `equals()` if available, else `===` |
|
|
32
42
|
|
|
33
|
-
-
|
|
43
|
+
## Field-Level Options
|
|
34
44
|
|
|
35
|
-
|
|
45
|
+
The `@partialEq` decorator supports:
|
|
36
46
|
|
|
37
|
-
|
|
47
|
+
- `skip` - Exclude the field from equality comparison
|
|
38
48
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<MacroExample before={data.examples.skip.before} after={data.examples.skip.after} />
|
|
49
|
+
## Example
|
|
42
50
|
|
|
43
51
|
```typescript
|
|
44
|
-
|
|
45
|
-
const user2 = new User(1, "Alice", new Date("2024-12-01"));
|
|
46
|
-
|
|
47
|
-
console.log(user1.equals(user2)); // true (createdAt is skipped)
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## Type Safety
|
|
51
|
-
|
|
52
|
-
The generated `equals()` method accepts `unknown` and performs runtime type checking:
|
|
53
|
-
|
|
54
|
-
<InteractiveMacro code={`/** @derive(PartialEq) */
|
|
52
|
+
@derive(PartialEq, Hash)
|
|
55
53
|
class User {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
this.name = name;
|
|
59
|
-
}
|
|
60
|
-
}`} />
|
|
61
|
-
|
|
62
|
-
```typescript
|
|
63
|
-
const user = new User("Alice");
|
|
64
|
-
|
|
65
|
-
console.log(user.equals(new User("Alice"))); // true
|
|
66
|
-
console.log(user.equals("Alice")); // false (not a User instance)
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## With Nested Objects
|
|
54
|
+
id: number;
|
|
55
|
+
name: string;
|
|
70
56
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
class Address {
|
|
75
|
-
city: string;
|
|
76
|
-
zip: string;
|
|
77
|
-
|
|
78
|
-
constructor(city: string, zip: string) {
|
|
79
|
-
this.city = city;
|
|
80
|
-
this.zip = zip;
|
|
81
|
-
}
|
|
57
|
+
@partialEq(skip) // Don't compare cached values
|
|
58
|
+
@hash(skip)
|
|
59
|
+
cachedScore: number;
|
|
82
60
|
}
|
|
83
61
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
}`} />
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
const addr1 = new Address("NYC", "10001");
|
|
97
|
-
const addr2 = new Address("NYC", "10001");
|
|
98
|
-
|
|
99
|
-
const p1 = new Person("Alice", addr1);
|
|
100
|
-
const p2 = new Person("Alice", addr2);
|
|
101
|
-
|
|
102
|
-
console.log(p1.equals(p2)); // true (deep equality via Address.equals)
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
## Interface Support
|
|
106
|
-
|
|
107
|
-
PartialEq works with interfaces. For interfaces, a namespace is generated with an `equals` function:
|
|
108
|
-
|
|
109
|
-
<MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
|
|
110
|
-
|
|
111
|
-
```typescript
|
|
112
|
-
const p1: Point = { x: 10, y: 20 };
|
|
113
|
-
const p2: Point = { x: 10, y: 20 };
|
|
114
|
-
const p3: Point = { x: 5, y: 5 };
|
|
115
|
-
|
|
116
|
-
console.log(Point.equals(p1, p2)); // true
|
|
117
|
-
console.log(Point.equals(p1, p3)); // false
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Enum Support
|
|
121
|
-
|
|
122
|
-
PartialEq works with enums. For enums, strict equality comparison is used:
|
|
123
|
-
|
|
124
|
-
<MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
|
|
125
|
-
|
|
126
|
-
```typescript
|
|
127
|
-
console.log(Status.equals(Status.Active, Status.Active)); // true
|
|
128
|
-
console.log(Status.equals(Status.Active, Status.Inactive)); // false
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Type Alias Support
|
|
132
|
-
|
|
133
|
-
PartialEq works with type aliases. For object types, field-by-field comparison is used:
|
|
134
|
-
|
|
135
|
-
<MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
|
|
136
|
-
|
|
137
|
-
```typescript
|
|
138
|
-
const p1: Point = { x: 10, y: 20 };
|
|
139
|
-
const p2: Point = { x: 10, y: 20 };
|
|
140
|
-
|
|
141
|
-
console.log(Point.equals(p1, p2)); // true
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
For union types, strict equality is used:
|
|
145
|
-
|
|
146
|
-
<InteractiveMacro code={`/** @derive(PartialEq) */
|
|
147
|
-
type ApiStatus = "loading" | "success" | "error";`} />
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
console.log(ApiStatus.equals("success", "success")); // true
|
|
151
|
-
console.log(ApiStatus.equals("success", "error")); // false
|
|
62
|
+
// Generated:
|
|
63
|
+
// equals(other: unknown): boolean {
|
|
64
|
+
// if (this === other) return true;
|
|
65
|
+
// if (!(other instanceof User)) return false;
|
|
66
|
+
// const typedOther = other as User;
|
|
67
|
+
// return this.id === typedOther.id &&
|
|
68
|
+
// this.name === typedOther.name;
|
|
69
|
+
// }
|
|
152
70
|
```
|
|
153
71
|
|
|
154
|
-
##
|
|
155
|
-
|
|
156
|
-
### Finding Items in Arrays
|
|
157
|
-
|
|
158
|
-
<InteractiveMacro code={`/** @derive(PartialEq) */
|
|
159
|
-
class Product {
|
|
160
|
-
sku: string;
|
|
161
|
-
name: string;
|
|
162
|
-
|
|
163
|
-
constructor(sku: string, name: string) {
|
|
164
|
-
this.sku = sku;
|
|
165
|
-
this.name = name;
|
|
166
|
-
}
|
|
167
|
-
}`} />
|
|
168
|
-
|
|
169
|
-
```typescript
|
|
170
|
-
const products = [
|
|
171
|
-
new Product("A1", "Widget"),
|
|
172
|
-
new Product("B2", "Gadget"),
|
|
173
|
-
new Product("C3", "Gizmo")
|
|
174
|
-
];
|
|
175
|
-
|
|
176
|
-
const target = new Product("B2", "Gadget");
|
|
177
|
-
const found = products.find(p => p.equals(target));
|
|
72
|
+
## Equality Contract
|
|
178
73
|
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Use with Hash
|
|
183
|
-
|
|
184
|
-
When using objects as keys in Map-like structures, combine PartialEq with Hash:
|
|
185
|
-
|
|
186
|
-
<InteractiveMacro code={`/** @derive(PartialEq, Hash) */
|
|
187
|
-
class Key {
|
|
188
|
-
id: number;
|
|
189
|
-
type: string;
|
|
190
|
-
|
|
191
|
-
constructor(id: number, type: string) {
|
|
192
|
-
this.id = id;
|
|
193
|
-
this.type = type;
|
|
194
|
-
}
|
|
195
|
-
}`} />
|
|
196
|
-
|
|
197
|
-
```typescript
|
|
198
|
-
const k1 = new Key(1, "user");
|
|
199
|
-
const k2 = new Key(1, "user");
|
|
74
|
+
When implementing `PartialEq`, consider also implementing `Hash`:
|
|
200
75
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
```
|
|
76
|
+
- **Reflexivity**: `a.equals(a)` is always true
|
|
77
|
+
- **Symmetry**: `a.equals(b)` implies `b.equals(a)`
|
|
78
|
+
- **Hash consistency**: Equal objects must have equal hash codes
|
|
@@ -1,188 +1,96 @@
|
|
|
1
1
|
# PartialOrd
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The `PartialOrd` macro generates a `compareTo()` method for **partial ordering**
|
|
4
|
+
comparison. This is analogous to Rust's `PartialOrd` trait, enabling comparison
|
|
5
|
+
between values where some pairs may be incomparable.
|
|
4
6
|
|
|
5
|
-
##
|
|
7
|
+
## Generated Output
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
| Type | Generated Code | Description |
|
|
10
|
+
|------|----------------|-------------|
|
|
11
|
+
| Class | `compareTo(other): Option<number>` | Instance method with optional result |
|
|
12
|
+
| Enum | `partialCompareEnumName(a: EnumName, b: EnumName): Option<number>` | Standalone function returning Option |
|
|
13
|
+
| Interface | `partialCompareInterfaceName(a: InterfaceName, b: InterfaceName): Option<number>` | Standalone function with Option |
|
|
14
|
+
| Type Alias | `partialCompareTypeName(a: TypeName, b: TypeName): Option<number>` | Standalone function with Option |
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
const t1 = new Temperature(20);
|
|
11
|
-
const t2 = new Temperature(30);
|
|
12
|
-
const t3 = new Temperature(20);
|
|
13
|
-
|
|
14
|
-
console.log(t1.compareTo(t2)); // -1 (t1 < t2)
|
|
15
|
-
console.log(t2.compareTo(t1)); // 1 (t2 > t1)
|
|
16
|
-
console.log(t1.compareTo(t3)); // 0 (t1 == t3)
|
|
16
|
+
## Configuration
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
The `functionNamingStyle` option in `macroforge.json` controls naming:
|
|
19
|
+
- `"suffix"` (default): Suffixes with type name (e.g., `partialCompareMyType`)
|
|
20
|
+
- `"prefix"`: Prefixes with type name (e.g., `myTypePartialCompare`)
|
|
21
|
+
- `"generic"`: Uses TypeScript generics (e.g., `partialCompare<T extends MyType>`)
|
|
22
|
+
- `"namespace"`: Legacy namespace wrapping
|
|
21
23
|
|
|
22
24
|
## Return Values
|
|
23
25
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
- `-1` → `this` is less than `other`
|
|
27
|
-
|
|
28
|
-
- `0` → `this` equals `other`
|
|
29
|
-
|
|
30
|
-
- `1` → `this` is greater than `other`
|
|
31
|
-
|
|
32
|
-
- `null` → Values are incomparable (e.g., different types)
|
|
33
|
-
|
|
34
|
-
## Comparison Logic
|
|
35
|
-
|
|
36
|
-
The PartialOrd macro compares fields in declaration order with type checking:
|
|
37
|
-
|
|
38
|
-
- `number` / `bigint` → Direct numeric comparison
|
|
39
|
-
|
|
40
|
-
- `string` → Uses `localeCompare()`
|
|
41
|
-
|
|
42
|
-
- `boolean` → `false < true`
|
|
26
|
+
Unlike `Ord`, `PartialOrd` returns an `Option<number>` to handle incomparable values:
|
|
43
27
|
|
|
44
|
-
- `
|
|
28
|
+
- **Option.some(-1)**: `this` is less than `other`
|
|
29
|
+
- **Option.some(0)**: `this` is equal to `other`
|
|
30
|
+
- **Option.some(1)**: `this` is greater than `other`
|
|
31
|
+
- **Option.none()**: Values are incomparable
|
|
45
32
|
|
|
46
|
-
|
|
33
|
+
## When to Use PartialOrd vs Ord
|
|
47
34
|
|
|
48
|
-
-
|
|
35
|
+
- **PartialOrd**: When some values may not be comparable
|
|
36
|
+
- Example: Floating-point NaN values
|
|
37
|
+
- Example: Mixed-type unions
|
|
38
|
+
- Example: Type mismatches between objects
|
|
49
39
|
|
|
50
|
-
- **
|
|
40
|
+
- **Ord**: When all values are guaranteed comparable (total ordering)
|
|
51
41
|
|
|
52
|
-
##
|
|
42
|
+
## Comparison Strategy
|
|
53
43
|
|
|
54
|
-
|
|
44
|
+
Fields are compared **lexicographically** in declaration order:
|
|
55
45
|
|
|
56
|
-
|
|
46
|
+
1. Compare first field
|
|
47
|
+
2. If incomparable, return `Option.none()`
|
|
48
|
+
3. If not equal, return that result wrapped in `Option.some()`
|
|
49
|
+
4. Otherwise, compare next field
|
|
50
|
+
5. Continue until a difference is found or all fields are equal
|
|
57
51
|
|
|
58
|
-
|
|
52
|
+
## Type-Specific Comparisons
|
|
59
53
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
54
|
+
| Type | Comparison Method |
|
|
55
|
+
|------|-------------------|
|
|
56
|
+
| `number`/`bigint` | Direct comparison, returns some() |
|
|
57
|
+
| `string` | `localeCompare()` wrapped in some() |
|
|
58
|
+
| `boolean` | false < true, wrapped in some() |
|
|
59
|
+
| null/undefined | Returns none() for mismatched nullability |
|
|
60
|
+
| Arrays | Lexicographic, propagates none() on incomparable elements |
|
|
61
|
+
| `Date` | Timestamp comparison, none() if invalid |
|
|
62
|
+
| Objects | Unwraps nested Option from compareTo() |
|
|
66
63
|
|
|
67
|
-
##
|
|
64
|
+
## Field-Level Options
|
|
68
65
|
|
|
69
|
-
|
|
66
|
+
The `@ord` decorator supports:
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
class Value {
|
|
73
|
-
amount: number;
|
|
68
|
+
- `skip` - Exclude the field from ordering comparison
|
|
74
69
|
|
|
75
|
-
|
|
76
|
-
this.amount = amount;
|
|
77
|
-
}
|
|
78
|
-
}`} />
|
|
70
|
+
## Example
|
|
79
71
|
|
|
80
72
|
```typescript
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
} else if (result < 0) {
|
|
86
|
-
return "less than";
|
|
87
|
-
} else if (result > 0) {
|
|
88
|
-
return "greater than";
|
|
89
|
-
} else {
|
|
90
|
-
return "equal";
|
|
91
|
-
}
|
|
73
|
+
@derive(PartialOrd)
|
|
74
|
+
class Temperature {
|
|
75
|
+
value: number | null; // null represents "unknown"
|
|
76
|
+
unit: string;
|
|
92
77
|
}
|
|
93
78
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
constructor(value: number) {
|
|
108
|
-
this.value = value;
|
|
109
|
-
}
|
|
110
|
-
}`} />
|
|
111
|
-
|
|
112
|
-
```typescript
|
|
113
|
-
const scores = [
|
|
114
|
-
new Score(100),
|
|
115
|
-
new Score(50),
|
|
116
|
-
new Score(75)
|
|
117
|
-
];
|
|
118
|
-
|
|
119
|
-
// Safe sort that handles null (treats null as equal)
|
|
120
|
-
scores.sort((a, b) => a.compareTo(b) ?? 0);
|
|
121
|
-
// Result: [Score(50), Score(75), Score(100)]
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
## Interface Support
|
|
125
|
-
|
|
126
|
-
PartialOrd works with interfaces. For interfaces, a namespace is generated with a `compareTo` function:
|
|
127
|
-
|
|
128
|
-
<MacroExample before={data.examples.interface.before} after={data.examples.interface.after} />
|
|
129
|
-
|
|
130
|
-
```typescript
|
|
131
|
-
const m1: Measurement = { value: 10, unit: "kg" };
|
|
132
|
-
const m2: Measurement = { value: 10, unit: "lb" };
|
|
133
|
-
|
|
134
|
-
console.log(Measurement.compareTo(m1, m2)); // 1 (kg > lb alphabetically)
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
## Enum Support
|
|
138
|
-
|
|
139
|
-
PartialOrd works with enums:
|
|
140
|
-
|
|
141
|
-
<MacroExample before={data.examples.enum.before} after={data.examples.enum.after} />
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
console.log(Size.compareTo(Size.Small, Size.Large)); // -1
|
|
145
|
-
console.log(Size.compareTo(Size.Large, Size.Small)); // 1
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
## Type Alias Support
|
|
149
|
-
|
|
150
|
-
PartialOrd works with type aliases:
|
|
151
|
-
|
|
152
|
-
<MacroExample before={data.examples.typeAlias.before} after={data.examples.typeAlias.after} />
|
|
153
|
-
|
|
154
|
-
```typescript
|
|
155
|
-
const i1: Interval = { start: 0, end: 10 };
|
|
156
|
-
const i2: Interval = { start: 0, end: 20 };
|
|
157
|
-
|
|
158
|
-
console.log(Interval.compareTo(i1, i2)); // -1
|
|
79
|
+
// Generated:
|
|
80
|
+
// compareTo(other: unknown): Option<number> {
|
|
81
|
+
// if (this === other) return Option.some(0);
|
|
82
|
+
// if (!(other instanceof Temperature)) return Option.none();
|
|
83
|
+
// const typedOther = other as Temperature;
|
|
84
|
+
// const cmp0 = ...; // Compare value field
|
|
85
|
+
// if (cmp0 === null) return Option.none();
|
|
86
|
+
// if (cmp0 !== 0) return Option.some(cmp0);
|
|
87
|
+
// const cmp1 = ...; // Compare unit field
|
|
88
|
+
// if (cmp1 === null) return Option.none();
|
|
89
|
+
// if (cmp1 !== 0) return Option.some(cmp1);
|
|
90
|
+
// return Option.some(0);
|
|
91
|
+
// }
|
|
159
92
|
```
|
|
160
93
|
|
|
161
|
-
##
|
|
94
|
+
## Required Import
|
|
162
95
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- **Ord** → Use when all values are always comparable (never returns null)
|
|
166
|
-
|
|
167
|
-
- **PartialOrd** → Use when comparing with `unknown` types or when some values might be incomparable
|
|
168
|
-
|
|
169
|
-
<InteractiveMacro code={`// PartialOrd is safer for public APIs that accept unknown input
|
|
170
|
-
/** @derive(PartialOrd) */
|
|
171
|
-
class SafeValue {
|
|
172
|
-
data: number;
|
|
173
|
-
constructor(data: number) {
|
|
174
|
-
this.data = data;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Can safely compare with any value
|
|
178
|
-
isGreaterThan(other: unknown): boolean {
|
|
179
|
-
const result = this.compareTo(other);
|
|
180
|
-
return result !== null && result > 0;
|
|
181
|
-
}
|
|
182
|
-
}`} />
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
const safe = new SafeValue(100);
|
|
186
|
-
console.log(safe.isGreaterThan(new SafeValue(50))); // true
|
|
187
|
-
console.log(safe.isGreaterThan("invalid")); // false
|
|
188
|
-
```
|
|
96
|
+
The generated code automatically adds an import for `Option` from `macroforge/utils`.
|