1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! # PartialOrd Macro Implementation
//!
//! The `PartialOrd` macro generates a `compareTo()` method for **partial ordering**
//! comparison. This is analogous to Rust's `PartialOrd` trait, enabling comparison
//! between values where some pairs may be incomparable.
//!
//! ## Generated Output
//!
//! | Type | Generated Code | Description |
//! |------|----------------|-------------|
//! | Class | `{className}PartialCompare(a, b)` + `static compareTo(a, b)` | Standalone function + static wrapper method |
//! | Enum | `{enumName}PartialCompare(a, b): number \| null` | Standalone function returning `number \| null` |
//! | Interface | `{ifaceName}PartialCompare(a, b): number \| null` | Standalone function returning `number \| null` |
//! | Type Alias | `{typeName}PartialCompare(a, b): number \| null` | Standalone function returning `number \| null` |
//!
//! Names use **camelCase** conversion (e.g., `Temperature` → `temperaturePartialCompare`).
//!
//! ## Return Values
//!
//! Unlike `Ord`, `PartialOrd` returns `number | null` to handle incomparable values:
//!
//! - **-1**: `a` is less than `b`
//! - **0**: `a` is equal to `b`
//! - **1**: `a` is greater than `b`
//! - **null**: Values are incomparable
//!
//! ## When to Use PartialOrd vs Ord
//!
//! - **PartialOrd**: When some values may not be comparable
//! - Example: Floating-point NaN values
//! - Example: Mixed-type unions
//! - Example: Type mismatches between objects
//!
//! - **Ord**: When all values are guaranteed comparable (total ordering)
//!
//! ## Comparison Strategy
//!
//! Fields are compared **lexicographically** in declaration order:
//!
//! 1. Compare first field
//! 2. If incomparable, return `null`
//! 3. If not equal, return that result
//! 4. Otherwise, compare next field
//! 5. Continue until a difference is found or all fields are equal
//!
//! ## Type-Specific Comparisons
//!
//! | Type | Comparison Method |
//! |------|-------------------|
//! | `number`/`bigint` | Direct subtraction (`a - b`) |
//! | `string` | `localeCompare()` |
//! | `boolean` | `false < true` (cast to number) |
//! | null/undefined | Returns `null` for mismatched nullability |
//! | Arrays | Lexicographic, propagates `null` on incomparable elements |
//! | `Date` | Timestamp comparison, `null` if invalid |
//! | Objects | Delegates to `compareTo()` if available |
//!
//! ## Field-Level Options
//!
//! The `@ord` decorator supports:
//!
//! - `skip` - Exclude the field from ordering comparison
//!
//! ## Example
//!
//! ```typescript
//! /** @derive(PartialOrd) */
//! class Temperature {
//! value: number | null;
//! unit: string;
//! }
//! ```
//!
//! Generated output:
//!
//! ```typescript
//! class Temperature {
//! value: number | null;
//! unit: string;
//!
//! static compareTo(a: Temperature, b: Temperature): number | null {
//! return temperaturePartialCompare(a, b);
//! }
//! }
//!
//! export function temperaturePartialCompare(a: Temperature, b: Temperature): number | null {
//! if (a === b) return 0;
//! const cmp0 = (() => {
//! if (typeof (a.value as any)?.compareTo === 'function') {
//! const optResult = (a.value as any).compareTo(b.value);
//! return optResult === null ? null : optResult;
//! }
//! return a.value === b.value ? 0 : null;
//! })();
//! if (cmp0 === null) return null;
//! if (cmp0 !== 0) return cmp0;
//! const cmp1 = a.unit.localeCompare(b.unit);
//! if (cmp1 === null) return null;
//! if (cmp1 !== 0) return cmp1;
//! return 0;
//! }
//! ```
//!
//! ## Return Type
//!
//! The generated functions return `number | null` where `null` indicates incomparable values.
pub
pub