diff --git a/assembly/ScaleSet.ts b/assembly/ScaleSet.ts new file mode 100644 index 0000000..672af2c --- /dev/null +++ b/assembly/ScaleSet.ts @@ -0,0 +1,79 @@ +import { CompactInt } from "./Int/CompactInt"; +import { BytesReader } from "./BytesReader"; +import { Codec } from "./interfaces/Codec"; +import { UnwrappableCodec } from "./interfaces/UnwrappableCodec"; + +/** + * @description SCALE Codec support for native Set type + */ +export class ScaleSet + extends Set + implements UnwrappableCodec> { + /** + * @description return underlying native type + */ + @inline + unwrap(): Set { + // TODO: remove unwrap? + return this; + } + + /** + * The number of bytes this Set has + */ + @inline + encodedLength(): i32 { + return this.toU8a().length; + } + /** + * Convert it to u8[] + * Length is encoded first, followed by all key and value encodings concatenated + */ + toU8a(): u8[] { + const values: T[] = this.values(); + let len: CompactInt = new CompactInt(values.length); + const result: Array> = [len.toU8a()]; + for (let i = 0; i < values.length; i++) { + result.push(values[i].toU8a()); + } + return result.flat(); + } + + /** + * @description Non-static constructor + * @param bytes + * @param index + */ + populateFromBytes(bytes: u8[], index: i32 = 0): i32 { + const bytesReader = new BytesReader(bytes, index); + const lenComp = bytesReader.readInto(); + for (let i: i32 = 0; i < lenComp.unwrap(); i++) { + const value = bytesReader.readInto(); + this.add(value); + } + + return bytesReader.currentIndex(); + } + + @operator("==") + eq(other: this): bool { + return this === other; + } + + @operator("!=") + notEq(other: this): bool { + return !this.eq(this); + } + + static fromU8a(input: u8[], index: i32 = 0): ScaleSet { + const set = new ScaleSet(); + const bytesReader = new BytesReader(input, index); + const len = bytesReader.readInto().unwrap(); + + for (let i: i32 = 0; i < len; i++) { + const val = bytesReader.readInto(); + set.add(val); + } + return set; + } +}