import type { Fr } from '@aztec/foundation/curves/bn254'; import { BufferReader, FieldReader, type Serializable, type Tuple, serializeToBuffer, serializeToFields, } from '@aztec/foundation/serialize'; import { inspect } from 'util'; export class ClaimedLengthArray { constructor( public array: Tuple, // Named `claimedLength` instead of `length` to avoid being confused with array.length. public claimedLength: number, ) {} static fromBuffer( buffer: Buffer | BufferReader, deserializer: { fromBuffer: (reader: BufferReader) => T; }, arrayLength: N, ): ClaimedLengthArray { const reader = BufferReader.asReader(buffer); const array = reader.readArray(arrayLength, deserializer) as Tuple; const claimedLength = reader.readNumber(); return new ClaimedLengthArray(array, claimedLength); } toBuffer() { return serializeToBuffer(this.array, this.claimedLength); } static fromFields( fields: Fr[] | FieldReader, deserializer: { fromFields: (reader: FieldReader) => T; }, arrayLength: N, ): ClaimedLengthArray { const reader = FieldReader.asReader(fields); const array = reader.readTuple(arrayLength, deserializer); const claimedLength = reader.readU32(); return new ClaimedLengthArray(array, claimedLength); } toFields() { return serializeToFields(this.array, this.claimedLength); } static empty( elem: { empty: () => T }, arraySize: number, ): ClaimedLengthArray { const array = Array(arraySize).fill(elem.empty()) as Tuple; return new ClaimedLengthArray(array, 0); } isEmpty() { return this.claimedLength === 0; } getActiveItems(): T[] { return this.array.slice(0, this.claimedLength); } getSize() { return this.toBuffer().length; } [inspect.custom]() { return `ClaimedLengthArray { array: [${this.getActiveItems() .map(x => inspect(x)) .join(', ')}], claimedLength: ${this.claimedLength}, `; } } export function ClaimedLengthArrayFromBuffer( deserializer: { fromBuffer: (reader: BufferReader) => T; }, arrayLength: N, ): { fromBuffer: (reader: BufferReader) => ClaimedLengthArray; } { return { fromBuffer: (reader: BufferReader) => ClaimedLengthArray.fromBuffer(reader, deserializer, arrayLength) }; } export function ClaimedLengthArrayFromFields( deserializer: { fromFields: (reader: FieldReader) => T; }, arrayLength: N, ): { fromFields: (reader: FieldReader) => ClaimedLengthArray; } { return { fromFields: (reader: FieldReader) => ClaimedLengthArray.fromFields(reader, deserializer, arrayLength) }; }