diff --git a/src/compound/struct.ts b/src/compound/struct.ts index fbdeea5..00dc858 100644 --- a/src/compound/struct.ts +++ b/src/compound/struct.ts @@ -4,6 +4,7 @@ import { type Options, type Packed, } from "../types/mod.ts"; +import { getBiggestAlignment } from "../util.ts"; export class Struct< T extends Record>, @@ -14,10 +15,7 @@ export class Struct< #record: Array<[string, AlignedType]>; constructor(input: T) { - // Find biggest alignment - const byteAlignment = Object.values(input) - .reduce((acc, x) => Math.max(acc, x.byteAlignment), 0); - super(byteAlignment); + super(getBiggestAlignment(input)); this.#record = Object.entries(input); } diff --git a/src/compound/tagged_union.ts b/src/compound/tagged_union.ts index 76719d8..d23b9cd 100644 --- a/src/compound/tagged_union.ts +++ b/src/compound/tagged_union.ts @@ -6,6 +6,7 @@ import { type Packed, type ValueOf, } from "../types/mod.ts"; +import { getBiggestAlignment } from "../util.ts"; type Fn = (value: T) => number; @@ -19,11 +20,12 @@ export class TaggedUnion< #variantFinder: Fn; #discriminant: AlignedType; - constructor(input: T, variantFinder: Fn, discriminantCodec: AlignedType = u8) { - // Find biggest alignment - const byteAlignment = Object.values(input) - .reduce((acc, x) => Math.max(acc, x.byteAlignment), 0); - super(byteAlignment); + constructor( + input: T, + variantFinder: Fn, + discriminantCodec: AlignedType = u8, + ) { + super(getBiggestAlignment(input)); this.#record = input; this.#variantFinder = variantFinder; this.#discriminant = discriminantCodec; diff --git a/src/compound/tuple.ts b/src/compound/tuple.ts index 96dc9c9..a9a9938 100644 --- a/src/compound/tuple.ts +++ b/src/compound/tuple.ts @@ -4,6 +4,7 @@ import { type Options, type Packed, } from "../types/mod.ts"; +import { getBiggestAlignment } from "../util.ts"; export class Tuple< T extends [...AlignedType[]], @@ -12,10 +13,7 @@ export class Tuple< #tupleTypes: T; constructor(types: T) { - // Find biggest alignment - const byteAlignment = Object.values(types) - .reduce((acc, x) => Math.max(acc, x.byteAlignment), 0); - super(byteAlignment); + super(getBiggestAlignment(types)); this.#tupleTypes = types; } diff --git a/src/util.ts b/src/util.ts index ba56a79..07976bb 100644 --- a/src/util.ts +++ b/src/util.ts @@ -1,3 +1,5 @@ +import type { AlignedType } from "./mod.ts"; + /** * The endianess of your machine, true if little endian and false if big endian. */ @@ -9,3 +11,11 @@ export const isLittleEndian = (() => { export const align = (unaligned: number, alignment: number) => (unaligned + alignment - 1) & ~(alignment - 1); + +type ArrayOrRecord = T[] | Record; + +export const getBiggestAlignment = ( + input: ArrayOrRecord>, +) => + Object.values(input) + .reduce((acc, x) => Math.max(acc, x.byteAlignment), 0);