From 81cc6f954762e5f3094cff5131ed7943e1ac5a8b Mon Sep 17 00:00:00 2001 From: jabonchan Date: Sun, 10 May 2026 14:55:24 -0400 Subject: [PATCH] Revert "added a few things" --- lib/classes.ts | 118 +----------- lib/constants.ts | 7 +- lib/format/colors.ts | 54 ------ lib/format/generate-description.ts | 36 ---- lib/format/generate-prefix.ts | 10 -- lib/format/internal-format.ts | 39 ---- lib/format/main.ts | 29 --- lib/helpers/alignof.ts | 4 + lib/helpers/checkers.ts | 8 + lib/helpers/create-array.ts | 20 +++ lib/helpers/format.ts | 178 +++++++++++++++++++ lib/helpers/mod.ts | 4 +- lib/helpers/read.ts | 27 ++- lib/helpers/sizeof.ts | 5 + lib/helpers/write.ts | 26 ++- lib/types/generics.ts | 21 +-- lib/types/unions.ts | 7 +- tests/array.ts | 0 tests/layout.ts | 8 +- {lib/helpers => tests/lib}/equals-pointer.ts | 0 tests/lib/object-equals.ts | 6 +- 21 files changed, 287 insertions(+), 320 deletions(-) delete mode 100644 lib/format/colors.ts delete mode 100644 lib/format/generate-description.ts delete mode 100644 lib/format/generate-prefix.ts delete mode 100644 lib/format/internal-format.ts delete mode 100644 lib/format/main.ts create mode 100644 lib/helpers/checkers.ts create mode 100644 lib/helpers/create-array.ts create mode 100644 lib/helpers/format.ts delete mode 100644 tests/array.ts rename {lib/helpers => tests/lib}/equals-pointer.ts (100%) diff --git a/lib/classes.ts b/lib/classes.ts index 0a83461..50ef0f9 100644 --- a/lib/classes.ts +++ b/lib/classes.ts @@ -1,7 +1,6 @@ import type { StructTypeof, UnionTypeof, - UnpackedNativeArray, UnpackedStruct, UnpackedUnion, } from "./types/generics.ts"; @@ -12,120 +11,10 @@ import { Alignment, Endianness } from "./types/enums.ts"; import { endianness } from "./helpers/endianness.ts"; import { alignof } from "./helpers/alignof.ts"; import { sizeof } from "./helpers/sizeof.ts"; -import { format } from "./format/main.ts"; +import { format } from "./helpers/format.ts"; import { write } from "./helpers/write.ts"; import { read } from "./helpers/read.ts"; -export class NativeArray< - const Declaration extends ValueDeclarationType = ValueDeclarationType, -> { - readonly isLittleEndian: boolean; - readonly isBigEndian: boolean; - readonly endianness: Endianness; - - readonly align: Alignment; - readonly type: Declaration; - - readonly byteLength: number; - readonly alignment: number; - readonly padding: number; - readonly length: number; - readonly size: number; - - constructor( - opts: { - length: number; - type: Declaration; - - endianness?: Endianness; - align?: Alignment; - size?: number; - }, - ) { - opts = { ...opts }; - - opts.endianness ??= Endianness.System; - opts.size = Math.max(opts.size ?? 1, 1); - - this.isLittleEndian = endianness(opts.endianness); - this.isBigEndian = !this.isLittleEndian; - this.endianness = this.isLittleEndian - ? Endianness.Little - : Endianness.Big; - - this.align = opts.align ?? Alignment.Natural; - this.size = sizeof(opts.type) * opts.length; - this.type = opts.type; - - this.alignment = alignof(this.type, this.align); - this.byteLength = Math.max(this.size, opts.size); - this.padding = this.byteLength - this.size; - this.length = opts.length; - } - - static isNativeArray(value: unknown): value is NativeArray { - return !!(value && typeof value === "object" && - value instanceof NativeArray); - } - - [Symbol.for("Deno.customInspect")]( - _: () => void, - opts: Deno.InspectOptions, - ): string { - return format(this, { colors: opts.colors ? true : false }); - } - - toString(): string { - return format(this, { colors: false }); - } - - offsetof(index: number): number { - return sizeof(this.type) * index; - } - - typeof(): Declaration { - return this.type; - } - - alignof(): number { - return this.alignment; - } - - pack( - array: UnpackedNativeArray, - buff: ArrayBuffer = new ArrayBuffer(this.byteLength), - offset = 0, - ): ArrayBuffer { - for (let i = 0; i < this.length; i++) { - const value = array[i]; - const index = this.offsetof(i); - - write(this.type, value, buff, index + offset, this.endianness); - } - - return buff; - } - - unpack(buff: ArrayBuffer, offset = 0): UnpackedNativeArray { - const array: UnpackedNativeArray = []; - - for (let i = 0; i < this.length; i++) { - const index = this.offsetof(i); - const value = read( - this.type, - buff, - index + offset, - this.endianness, - ); - - // @ts-ignore - Yeah this works on runtime properly. - array.push(value); - } - - return array; - } -} - export class Struct< const Declaration extends readonly { name: string; @@ -200,8 +89,7 @@ export class Struct< } static isStruct(value: unknown): value is Struct { - return !!(value && typeof value === "object" && - value instanceof Struct); + return value instanceof Struct; } [Symbol.for("Deno.customInspect")]( @@ -407,7 +295,7 @@ export class Union< } static isUnion(value: unknown): value is Union { - return !!(value && typeof value === "object" && value instanceof Union); + return value instanceof Union; } [Symbol.for("Deno.customInspect")]( diff --git a/lib/constants.ts b/lib/constants.ts index 8a03b05..3f227be 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -21,10 +21,9 @@ const nativeChar = isWindows ? "i8" : "u8"; const testBuffer: ArrayBuffer = new ArrayBuffer(4); new DataView(testBuffer).setUint32(0, 0x00_00_00_01, true); -export const SystemEndianness: enums.Endianness = - new Uint8Array(testBuffer)[0] === 0x01 - ? enums.Endianness.Little - : enums.Endianness.Big; +export const SystemEndianness: enums.Endianness = new Uint8Array(testBuffer)[0] === 0x01 + ? enums.Endianness.Little + : enums.Endianness.Big; export const Platform = { os: Deno.build.os, diff --git a/lib/format/colors.ts b/lib/format/colors.ts deleted file mode 100644 index 5e4fa75..0000000 --- a/lib/format/colors.ts +++ /dev/null @@ -1,54 +0,0 @@ -export const ANSIColors = { - // Reset - Reset: "\x1b[0m", - - // Text styles - Bold: "\x1b[1m", - Dim: "\x1b[2m", - Italic: "\x1b[3m", - Underline: "\x1b[4m", - Blink: "\x1b[5m", - Inverse: "\x1b[7m", - Hidden: "\x1b[8m", - Strikethrough: "\x1b[9m", - - // Foreground colors - Black: "\x1b[30m", - Red: "\x1b[31m", - Green: "\x1b[32m", - Yellow: "\x1b[33m", - Blue: "\x1b[34m", - Magenta: "\x1b[35m", - Cyan: "\x1b[36m", - White: "\x1b[37m", - - // Bright foreground colors - BrightBlack: "\x1b[90m", - BrightRed: "\x1b[91m", - BrightGreen: "\x1b[92m", - BrightYellow: "\x1b[93m", - BrightBlue: "\x1b[94m", - BrightMagenta: "\x1b[95m", - BrightCyan: "\x1b[96m", - BrightWhite: "\x1b[97m", - - // Background colors - BgBlack: "\x1b[40m", - BgRed: "\x1b[41m", - BgGreen: "\x1b[42m", - BgYellow: "\x1b[43m", - BgBlue: "\x1b[44m", - BgMagenta: "\x1b[45m", - BgCyan: "\x1b[46m", - BgWhite: "\x1b[47m", - - // Bright background colors - BgBrightBlack: "\x1b[100m", - BgBrightRed: "\x1b[101m", - BgBrightGreen: "\x1b[102m", - BgBrightYellow: "\x1b[103m", - BgBrightBlue: "\x1b[104m", - BgBrightMagenta: "\x1b[105m", - BgBrightCyan: "\x1b[106m", - BgBrightWhite: "\x1b[107m", -} as const; \ No newline at end of file diff --git a/lib/format/generate-description.ts b/lib/format/generate-description.ts deleted file mode 100644 index f2cac0d..0000000 --- a/lib/format/generate-description.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { NativeArray, Struct, Union } from "../classes.ts"; - -import { Alignment, Endianness } from "../types/enums.ts"; -import { ANSIColors as C } from "./colors.ts"; -import { hexify } from "../helpers/hexify.ts"; - -export function generateDescription( - value: Struct | Union | NativeArray, - tab: string, -): string { - let formatted = ""; - - formatted += `\n${tab}${C.BrightBlack}Endianness: ${C.Yellow}${ - value.endianness === Endianness.Little ? "Little" : "Big" - }`; - - formatted += `\n${tab}${C.BrightBlack}Alignment: ${C.Yellow}${ - hexify(value.alignment) - }:${value.alignment} ${ - value.align === Alignment.Natural ? "Natural" : "Packed" - }`; - - formatted += `\n${tab}${C.BrightBlack}Padding: ${C.Yellow}${ - hexify(value.padding) - }:${value.padding}`; - - formatted += `\n${tab}${C.BrightBlack}Total Size: ${C.Yellow}${ - hexify(value.byteLength) - }:${value.byteLength}`; - - formatted += `\n${tab}${C.BrightBlack}Size: ${C.Yellow}${ - hexify(value.size) - }:${value.size}`; - - return formatted; -} \ No newline at end of file diff --git a/lib/format/generate-prefix.ts b/lib/format/generate-prefix.ts deleted file mode 100644 index 1390902..0000000 --- a/lib/format/generate-prefix.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ANSIColors as C } from "./colors.ts"; -import { hexify } from "../helpers/hexify.ts"; - -export function generatePrefix(offset: number, size: number): string { - return `${C.Reset}${C.BrightBlack}Offset:${C.Yellow}${ - hexify(offset) - }:${offset} ${C.White}Size:${C.Yellow}${ - hexify(size) - }:${size}${C.BrightBlack})`; -} \ No newline at end of file diff --git a/lib/format/internal-format.ts b/lib/format/internal-format.ts deleted file mode 100644 index 73548a3..0000000 --- a/lib/format/internal-format.ts +++ /dev/null @@ -1,39 +0,0 @@ -import type { ValueDeclarationType } from "../types/unions.ts"; - -import { NativeArray, Struct, Union } from "../classes.ts"; -import { generateDescription } from "./generate-description.ts"; -import { ANSIColors as C } from "./colors.ts"; -import { generatePrefix } from "./generate-prefix.ts"; -import { sizeof } from "../helpers/sizeof.ts"; - -export function internalFormat( - type: ValueDeclarationType, - opts: { - name: string; - ident: number; - spaces: number; - offset: number; - colors: boolean; - }, -): string { - const spaces = { - initial: " ".repeat(opts.spaces * opts.ident++), - secondary: " ".repeat(opts.spaces * opts.ident), - } - - let formatted = spaces.initial + generatePrefix(opts.offset, sizeof(type)); - - switch (true) { - case typeof type === "string": { - return `${formatted + C.Magenta} ${type} ${C.Yellow + opts.name}`; - } - - case NativeArray.isNativeArray(type): { - formatted += - formatted += generateDescription(type, spaces.secondary); - break; - } - } - - return ""; -} \ No newline at end of file diff --git a/lib/format/main.ts b/lib/format/main.ts deleted file mode 100644 index 813bc5f..0000000 --- a/lib/format/main.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { ValueDeclarationType } from "../types/unions.ts"; -import { internalFormat } from "./internal-format.ts"; - -export function format( - type: ValueDeclarationType, - opts: { - name?: string; - ident?: number; - spaces?: number; - offset?: number; - colors?: boolean; - } = {}, -): string { - const newOpts = { - name: "unnamed", - ident: 0, - spaces: 4, - offset: 0, - colors: false, - ...opts, - }; - - const formatted = internalFormat(type, newOpts); - - // deno-lint-ignore no-control-regex - if (!opts.colors) return formatted.replace(/\x1b\[\d*m/g, ""); - - return formatted; -} diff --git a/lib/helpers/alignof.ts b/lib/helpers/alignof.ts index 022db52..c4c6782 100644 --- a/lib/helpers/alignof.ts +++ b/lib/helpers/alignof.ts @@ -2,6 +2,7 @@ import type { ValueDeclarationType } from "../types/unions.ts"; import { Alignment } from "../types/enums.ts"; import { sizeof } from "./sizeof.ts"; +import { isArrayField } from "./checkers.ts"; export function alignof( type: ValueDeclarationType, @@ -15,6 +16,9 @@ export function alignof( case "string": return size; case "object": + if (isArrayField(type)) return alignof(type.type, align); return type.alignment; } + + return size; } diff --git a/lib/helpers/checkers.ts b/lib/helpers/checkers.ts new file mode 100644 index 0000000..906fe7b --- /dev/null +++ b/lib/helpers/checkers.ts @@ -0,0 +1,8 @@ +import type { ValueDeclarationType } from "../types/unions.ts"; + +export function isArrayField( + type: unknown, +): type is { readonly length: number; readonly type: ValueDeclarationType } { + return type !== null && typeof type === "object" && "length" in type && + "type" in type; +} diff --git a/lib/helpers/create-array.ts b/lib/helpers/create-array.ts new file mode 100644 index 0000000..e01b37e --- /dev/null +++ b/lib/helpers/create-array.ts @@ -0,0 +1,20 @@ +import type { Alignment, Endianness } from "../types/enums.ts"; +import type { ValueDeclarationType } from "../types/unions.ts"; +import { Union } from "../classes.ts"; + +export function createArray< + const Declaration extends ValueDeclarationType = ValueDeclarationType, +>( + type: Declaration, + length: number, + opts: { size?: number; endianness?: Endianness; align?: Alignment } = {}, +): Union<{ + readonly "[ARRAY_ITEMS]": { + readonly length: number; + readonly type: Declaration; + }; +}> { + return new Union({ + "[ARRAY_ITEMS]": { length, type }, + }, opts); +} diff --git a/lib/helpers/format.ts b/lib/helpers/format.ts new file mode 100644 index 0000000..1d698cf --- /dev/null +++ b/lib/helpers/format.ts @@ -0,0 +1,178 @@ +import type { ValueDeclarationType } from "../types/unions.ts"; + +import { Alignment, Endianness } from "../types/enums.ts"; +import { Struct, Union } from "../classes.ts"; +import { isArrayField } from "./checkers.ts"; +import { hexify } from "./hexify.ts"; +import { sizeof } from "./sizeof.ts"; + +function generatePrefix(offset: number, size: number): string { + return `\x1b[90m(\x1b[37mOffset:\x1b[33m${ + hexify(offset) + }:${offset} \x1b[37mSize:\x1b[33m${hexify(size)}:${size}\x1b[90m)`; +} + +function generateDescription(value: Struct | Union, tab: string): string { + let formatted = ""; + + formatted += `\n${tab}\x1b[90mEndianness: \x1b[33m${ + value.endianness === Endianness.Little ? "Little" : "Big" + }`; + formatted += `\n${tab}\x1b[90mAlignment: \x1b[33m${ + hexify(value.alignment) + }:${value.alignment} ${ + value.align === Alignment.Natural ? "Natural" : "Packed" + }`; + formatted += `\n${tab}\x1b[90mPadding: \x1b[33m${ + hexify(value.padding) + }:${value.padding}`; + formatted += `\n${tab}\x1b[90mTotal Size: \x1b[33m${ + hexify(value.byteLength) + }:${value.byteLength}`; + formatted += `\n${tab}\x1b[90mSize: \x1b[33m${ + hexify(value.size) + }:${value.size}`; + + return formatted; +} + +export function format( + value: Struct | Union, + opts: { + name?: string; + ident?: number; + spaces?: number; + offset?: number; + colors?: boolean; + } = {}, +): string { + const newOpts = { + name: "unnamed", + ident: 0, + spaces: 4, + offset: 0, + colors: false, + ...opts, + }; + const prefix = " ".repeat(newOpts.spaces * newOpts.ident++); + const tab = " ".repeat(newOpts.spaces * newOpts.ident); + + let formatted = ""; + + if (Struct.isStruct(value)) { + formatted += prefix; + formatted += generatePrefix(newOpts.offset, value.size); + formatted += ` \x1b[35mstructure \x1b[33m${newOpts.name} \x1b[90m{`; + formatted += generateDescription(value, tab); + + const entries = Object.entries(value.fields).sort((a, b) => { + const fieldA = a[1] as unknown as { + offset: number; + type: ValueDeclarationType; + }; + const fieldB = b[1] as unknown as { + offset: number; + type: ValueDeclarationType; + }; + + return fieldA.offset - fieldB.offset; + }); + + if (entries.length) { + formatted += "\n"; + + for (const [name, field] of entries) { + const { offset, type } = field as unknown as { + offset: number; + type: ValueDeclarationType; + }; + + if (Struct.isStruct(type) || Union.isUnion(type)) { + formatted += "\n" + + format(type, { + ...newOpts, + name, + offset: newOpts.offset + offset, + }); + continue; + } + + if (isArrayField(type)) { + if ( + Struct.isStruct(type.type) || Union.isUnion(type.type) + ) { + formatted += `\n${ + format(type.type, { + ...newOpts, + name, + offset: newOpts.offset + offset, + }) + }\x1b[35m[\x1b[33m${type.length}\x1b[35m] \x1b[33m${name}\x1b[0m`; + continue; + } + + formatted += `\n${tab}${ + generatePrefix(newOpts.offset + offset, sizeof(type)) + } \x1b[35marray[\x1b[33m${type.length}\x1b[35m] \x1b[33m${name}\x1b[0m`; + continue; + } + + formatted += `\n${tab}${ + generatePrefix(newOpts.offset + offset, sizeof(type)) + } \x1b[35m${type} \x1b[33m${name}\x1b[0m`; + } + } + + formatted = formatted + `\n${prefix}\x1b[90m}\x1b[0m`; + // deno-lint-ignore no-control-regex + if (!opts.colors) return formatted.replace(/\x1b\[\d*m/g, ""); + return formatted; + } + + value = value as Union; + + formatted += prefix; + formatted += generatePrefix(newOpts.offset, value.size); + formatted += ` \x1b[35munion \x1b[33m${newOpts.name} \x1b[90m{`; + formatted += generateDescription(value, tab); + + const entries = Object.entries(value.fields); + + if (entries.length) { + formatted += "\n"; + + for (const [name, type] of entries) { + if (Struct.isStruct(type) || Union.isUnion(type)) { + formatted += "\n" + format(type, { ...newOpts, name }); + continue; + } + + if (isArrayField(type)) { + if (Struct.isStruct(type.type) || Union.isUnion(type.type)) { + formatted += `\n${ + format(type.type, { + ...newOpts, + name, + offset: newOpts.offset, + }) + }\x1b[35m[\x1b[33m${type.length}\x1b[35m] \x1b[33m${name}\x1b[0m`; + continue; + } + + formatted += `\n${tab}${ + generatePrefix(newOpts.offset, sizeof(type)) + } \x1b[35m${type.type}[\x1b[33m${type.length}\x1b[35m] \x1b[33m${name}\x1b[0m`; + continue; + } + + formatted += `\n${tab}${ + generatePrefix(newOpts.offset, sizeof(type)) + } \x1b[35m${type} \x1b[33m${name}\x1b[0m`; + } + } + + formatted = formatted + `\n${prefix}\x1b[90m}\x1b[0m`; + // deno-lint-ignore no-control-regex + if (!opts.colors) return formatted.replace(/\x1b\[\d*m/g, ""); + return formatted; +} diff --git a/lib/helpers/mod.ts b/lib/helpers/mod.ts index fd927ee..593b3b8 100644 --- a/lib/helpers/mod.ts +++ b/lib/helpers/mod.ts @@ -1,5 +1,5 @@ -export * from "./equals-pointer.ts"; +export * from "./create-array.ts"; export * from "./offsetof.ts"; export * from "./alignof.ts"; export * from "./sizeof.ts"; -export * from "./memory.ts"; \ No newline at end of file +export * from "./memory.ts"; diff --git a/lib/helpers/read.ts b/lib/helpers/read.ts index f203f7e..1496ff1 100644 --- a/lib/helpers/read.ts +++ b/lib/helpers/read.ts @@ -1,8 +1,10 @@ import type { ValueDeclarationType } from "../types/unions.ts"; -import { NativeArray, Struct, Union } from "../classes.ts"; +import { Struct, Union } from "../classes.ts"; +import { isArrayField } from "./checkers.ts"; import { Endianness } from "../types/enums.ts"; import { Platform } from "../constants.ts"; +import { sizeof } from "./sizeof.ts"; import { create } from "./mod.ts"; export function read( @@ -14,10 +16,25 @@ export function read( const isLittleEndian = endianness === Endianness.Little; const view = new DataView(buff); - if ( - Struct.isStruct(type) || Union.isUnion(type) || - NativeArray.isNativeArray(type) - ) { + if (isArrayField(type)) { + const array = []; + const elementSize = sizeof(type.type); + + for (let i = 0; i < type.length; i++) { + array.push( + read( + type.type, + buff, + offset + elementSize * i, + endianness, + ), + ); + } + + return array; + } + + if (type instanceof Struct || type instanceof Union) { return (type as { unpack(buff: ArrayBuffer, offset: number): unknown }) .unpack(buff, offset); } diff --git a/lib/helpers/sizeof.ts b/lib/helpers/sizeof.ts index 023560d..75a409a 100644 --- a/lib/helpers/sizeof.ts +++ b/lib/helpers/sizeof.ts @@ -1,4 +1,5 @@ import type { ValueDeclarationType } from "../types/unions.ts"; +import { isArrayField } from "./checkers.ts"; import * as constants from "../constants.ts"; @@ -39,7 +40,11 @@ export function sizeof( break; } + case "number": + return type; + default: + if (isArrayField(type)) return type.length * sizeof(type.type); return type.byteLength; } } diff --git a/lib/helpers/write.ts b/lib/helpers/write.ts index 16815ed..cb36ff7 100644 --- a/lib/helpers/write.ts +++ b/lib/helpers/write.ts @@ -1,9 +1,11 @@ import type { TypedArray, ValueDeclarationType } from "../types/unions.ts"; -import { NativeArray, Struct, Union } from "../classes.ts"; +import { Struct, Union } from "../classes.ts"; +import { isArrayField } from "./checkers.ts"; import { Endianness } from "../types/enums.ts"; import { Platform } from "../constants.ts"; import { address } from "./memory.ts"; +import { sizeof } from "./sizeof.ts"; export function write( type: ValueDeclarationType, @@ -15,10 +17,24 @@ export function write( const isLittleEndian = endianness === Endianness.Little; const view = new DataView(buff); - if ( - Struct.isStruct(type) || Union.isUnion(type) || - NativeArray.isNativeArray(type) - ) { + if (isArrayField(type)) { + const array = Array.from(value as ArrayLike); + const elementSize = sizeof(type.type); + + for (let i = 0; i < type.length; i++) { + write( + type.type, + array[i], + buff, + offset + elementSize * i, + endianness, + ); + } + + return; + } + + if (Struct.isStruct(type) || Union.isUnion(type)) { // @ts-ignore - Too lazy to fix this type problem type.pack(value, buff, offset); return; diff --git a/lib/types/generics.ts b/lib/types/generics.ts index 2a18089..eb2e751 100644 --- a/lib/types/generics.ts +++ b/lib/types/generics.ts @@ -1,5 +1,5 @@ import type { TypedArray, ValueDeclarationType } from "./unions.ts"; -import type { NativeArray, Struct, Union } from "../classes.ts"; +import type { Struct, Union } from "../classes.ts"; type StructTypeofLookup< Declaration extends readonly { @@ -37,8 +37,10 @@ export type UnpackedValue = Type extends Struct ? UnpackedStruct : Type extends Union ? UnpackedUnion - : Type extends NativeArray - ? UnpackedNativeArray + : Type extends { + readonly length: number; + readonly type: infer ElementType extends ValueDeclarationType; + } ? UnpackedValue[] : Type extends "u8" | "i8" | "u16" | "i16" | "u32" | "i32" | "f32" | "f64" ? number : Type extends "u64" | "i64" | "isize" | "usize" ? bigint @@ -84,12 +86,7 @@ export type UnpackedStruct< [K in Declaration[number] as K["name"]]: UnpackedValue; }; -export type UnpackedNativeArray< - Declaration extends ValueDeclarationType = ValueDeclarationType, -> = UnpackedValue[]; - -export type ExtractDeclaration = - Value extends Struct ? Declaration - : Value extends Union ? Declaration - : Value extends NativeArray ? Declaration - : never; +export type ExtractDeclaration = Value extends + Struct ? Declaration + : Value extends Union ? Declaration + : never; diff --git a/lib/types/unions.ts b/lib/types/unions.ts index cd09ecd..9e988e3 100644 --- a/lib/types/unions.ts +++ b/lib/types/unions.ts @@ -1,4 +1,4 @@ -import type { NativeArray, Struct, Union } from "../classes.ts"; +import type { Struct, Union } from "../classes.ts"; export type TypedArray = | Uint8Array @@ -20,4 +20,7 @@ export type ValueDeclarationType = | PrimitiveDeclarationType | Union | Struct - | NativeArray; + | { + readonly length: number; + readonly type: ValueDeclarationType; + }; diff --git a/tests/array.ts b/tests/array.ts deleted file mode 100644 index e69de29..0000000 diff --git a/tests/layout.ts b/tests/layout.ts index f1ff732..e3ae78c 100644 --- a/tests/layout.ts +++ b/tests/layout.ts @@ -52,7 +52,7 @@ Deno.test("ABI: union layout", () => { const U = new deeplevel.Union({ a: t["signed char"], b: t["double"], - c: new deeplevel.NativeArray({ type: t["int"], length: 3 }), + c: h.createArray(t["int"], 3), }); test.assert(h.alignof(U) === 8, "U alignment"); @@ -67,7 +67,7 @@ Deno.test("ABI: array of structs", () => { ], }); - const Arr = new deeplevel.NativeArray({ type: S, length: 3 }); + const Arr = h.createArray(S, 3); test.assert(h.sizeof(S) === 8, "S size"); test.assert(h.alignof(S) === 4, "S alignment"); @@ -194,7 +194,7 @@ Deno.test("ABI: deep nesting (union -> struct -> union)", () => { const U2 = new deeplevel.Union({ a: S, - b: new deeplevel.NativeArray({ type: t["int"], length: 3 }), // 12 + b: h.createArray(t["int"], 3), // 12 }); // max size = 16, align = 8 -> size = 16 @@ -250,7 +250,7 @@ Deno.test("ABI: struct with array of unions", () => { }); // size = 8, align = 8 - const Arr = new deeplevel.NativeArray({ type: U, length: 3 }); + const Arr = h.createArray(U, 3); // size = 24 const S = new deeplevel.Struct({ diff --git a/lib/helpers/equals-pointer.ts b/tests/lib/equals-pointer.ts similarity index 100% rename from lib/helpers/equals-pointer.ts rename to tests/lib/equals-pointer.ts diff --git a/tests/lib/object-equals.ts b/tests/lib/object-equals.ts index 5aa8a72..0dd26ee 100644 --- a/tests/lib/object-equals.ts +++ b/tests/lib/object-equals.ts @@ -1,5 +1,5 @@ import type { Indexable, RegularObject } from "./types.ts"; -import * as deeplevel from "../../mod.ts" +import { equalsPointer, isPointer } from "./equals-pointer.ts"; function isObject(value: unknown): value is Indexable { return typeof value === "object" && value !== null; @@ -71,8 +71,8 @@ function objectEqualsInternal( throw new Error(errorMessage); } - if (deeplevel.helpers.isPointer(value) || deeplevel.helpers.isPointer(otherValue)) { - if (!deeplevel.helpers.equalsPointer(value, otherValue)) { + if (isPointer(value) || isPointer(otherValue)) { + if (!equalsPointer(value, otherValue)) { throw new Error( errorMessage + " (Pointers addresses don't match)", );