Skip to content

Commit 9bc1a07

Browse files
committed
Added .packed and .align helpers to struct and @struct
1 parent 01ae9a8 commit 9bc1a07

File tree

4 files changed

+36
-10
lines changed

4 files changed

+36
-10
lines changed

src/decorators.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,16 @@ export function struct(name: string, ...options: Options[]) {
148148
};
149149
}
150150

151+
struct.packed = function (name: string, ...options: Options[]) {
152+
return struct(name, ...options, { isPacked: true });
153+
};
154+
155+
struct.align = function (alignment: number) {
156+
return function (name: string, ...options: Options[]) {
157+
return struct(name, ...options, { alignment });
158+
};
159+
};
160+
151161
/**
152162
* deprecated Use the new `union` function instead.
153163
*/

src/structs.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export function struct<const T extends Record<string, FieldConfigInit>>(
143143
return _struct;
144144
}
145145

146-
struct.extend = function <const T extends Record<string, FieldConfigInit<Type<unknown>>>, const Base extends {}>(
146+
struct.extend = function <const T extends Record<string, FieldConfigInit>, const Base extends {}>(
147147
base: StructConstructor<Base>,
148148
structName: string,
149149
fieldDecls: T,
@@ -152,6 +152,24 @@ struct.extend = function <const T extends Record<string, FieldConfigInit<Type<un
152152
return struct<typeof base.fields & T>(structName, { ...base.fields, ...fieldDecls }, ...options);
153153
};
154154

155+
struct.packed = function <const T extends Record<string, FieldConfigInit>>(
156+
structName: string,
157+
fieldDecls: T,
158+
...options: Options[]
159+
): StructConstructor<StructValue<T>> {
160+
return struct(structName, fieldDecls, ...options, { isPacked: true });
161+
};
162+
163+
struct.align = function (alignment: number) {
164+
return function <const T extends Record<string, FieldConfigInit>>(
165+
structName: string,
166+
fieldDecls: T,
167+
...options: Options[]
168+
): StructConstructor<StructValue<T>> {
169+
return struct(structName, fieldDecls, ...options, { alignment });
170+
};
171+
};
172+
155173
export function union<const T extends Record<string, FieldConfigInit>>(
156174
unionName: string,
157175
fieldDecls: T,

tests/struct-decorators-dynamic.test.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@ import assert from 'node:assert';
22
import { closeSync, openSync, readSync, writeFileSync } from 'node:fs';
33
import { join } from 'node:path';
44
import { encodeASCII } from 'utilium/string.js';
5-
import { sizeof } from '../src/misc.js';
65
import { $from, field, struct, types as t } from '../src/decorators.js';
7-
import { packed } from '../src/attributes.js';
6+
import { sizeof } from '../src/misc.js';
87

9-
@struct(packed)
8+
@struct.packed('Duck')
109
class Duck extends $from.typed(Uint8Array) {
1110
@t.uint8 public accessor name_length: number = 0;
1211
@t.char(64, { countedBy: 'name_length' }) public accessor name!: Uint8Array;
@@ -17,7 +16,7 @@ class Duck extends $from.typed(Uint8Array) {
1716

1817
assert.equal(sizeof(Duck), 77);
1918

20-
@struct(packed)
19+
@struct.packed('MamaDuck')
2120
class MamaDuck extends Duck {
2221
@t.uint16 public accessor n_ducklings: number = 0;
2322

tests/struct-decorators.test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import assert from 'node:assert';
33
import { join } from 'path';
44
import { BufferView } from 'utilium/buffer.js';
55
import { decodeASCII, encodeASCII } from 'utilium/string.js';
6-
import { packed } from '../src/attributes.js';
76
import { $from, field, struct, types as t } from '../src/decorators.js';
87
import { array } from '../src/fields.js';
98
import { sizeof } from '../src/misc.js';
@@ -13,7 +12,7 @@ enum Some {
1312
one = 2,
1413
}
1514

16-
@struct(packed)
15+
@struct.packed('Header')
1716
class Header extends $from(BufferView) {
1817
@t.char(4) public accessor magic_start = encodeASCII('test');
1918

@@ -24,7 +23,7 @@ class Header extends $from(BufferView) {
2423

2524
assert.equal(sizeof(Header), 10);
2625

27-
@struct(packed)
26+
@struct.packed('AnotherHeader')
2827
class AnotherHeader extends Header {
2928
@t.uint64 public accessor _plus: bigint = 0x12345678n;
3029

@@ -33,15 +32,15 @@ class AnotherHeader extends Header {
3332

3433
assert.equal(sizeof(AnotherHeader), sizeof(Header) + 10);
3534

36-
@struct(packed)
35+
@struct.packed('Segment')
3736
class Segment extends $from(BufferView) {
3837
@t.uint64 public accessor id = 0x021;
3938
@t.uint32(64) public accessor data: ArrayLike<number> = [];
4039
}
4140

4241
assert.equal(sizeof(Segment), 264);
4342

44-
@struct(packed)
43+
@struct.packed('BinObject')
4544
class BinObject extends $from(Uint8Array) {
4645
@field(AnotherHeader) public accessor header = new AnotherHeader();
4746

0 commit comments

Comments
 (0)