feat(core): event queue, Ethernet, switch, ARP, IPv4, ICMP, routing and firewall
First slice of the TypeScript port of the filius-ipad runtime engine, with 29 tests ported from the Swift suite. Parts not ported yet throw NotPortedError instead of guessing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Structural equality for the runtime's value types — what Swift's synthesized
|
||||
* `Equatable` gives a struct or enum for free. Handles plain objects, arrays,
|
||||
* `Uint8Array`, `Map` and `Set`; everything else is compared with `Object.is`.
|
||||
*/
|
||||
export function deepEqual(lhs: unknown, rhs: unknown): boolean {
|
||||
if (Object.is(lhs, rhs)) return true;
|
||||
if (typeof lhs !== 'object' || typeof rhs !== 'object' || lhs === null || rhs === null) {
|
||||
return false;
|
||||
}
|
||||
if (lhs instanceof Uint8Array || rhs instanceof Uint8Array) {
|
||||
if (!(lhs instanceof Uint8Array && rhs instanceof Uint8Array)) return false;
|
||||
return lhs.length === rhs.length && lhs.every((byte, index) => byte === rhs[index]);
|
||||
}
|
||||
if (Array.isArray(lhs) || Array.isArray(rhs)) {
|
||||
if (!(Array.isArray(lhs) && Array.isArray(rhs)) || lhs.length !== rhs.length) return false;
|
||||
return lhs.every((item, index) => deepEqual(item, rhs[index]));
|
||||
}
|
||||
if (lhs instanceof Map || rhs instanceof Map) {
|
||||
if (!(lhs instanceof Map && rhs instanceof Map) || lhs.size !== rhs.size) return false;
|
||||
for (const [key, value] of lhs) {
|
||||
if (!rhs.has(key) || !deepEqual(value, rhs.get(key))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (lhs instanceof Set || rhs instanceof Set) {
|
||||
if (!(lhs instanceof Set && rhs instanceof Set) || lhs.size !== rhs.size) return false;
|
||||
for (const value of lhs) if (!rhs.has(value)) return false;
|
||||
return true;
|
||||
}
|
||||
const leftKeys = Object.keys(lhs).filter((key) => (lhs as Record<string, unknown>)[key] !== undefined);
|
||||
const rightKeys = Object.keys(rhs).filter((key) => (rhs as Record<string, unknown>)[key] !== undefined);
|
||||
if (leftKeys.length !== rightKeys.length) return false;
|
||||
return leftKeys.every((key) =>
|
||||
deepEqual((lhs as Record<string, unknown>)[key], (rhs as Record<string, unknown>)[key]),
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user