diff --git a/borsh-ts/index.ts b/borsh-ts/index.ts index afeed2ad..b61f4574 100644 --- a/borsh-ts/index.ts +++ b/borsh-ts/index.ts @@ -273,7 +273,11 @@ function serializeField(schema: Schema, fieldName: string, value: any, fieldType } } -function serializeStruct(schema: Schema, obj: any, writer: any) { +function serializeStruct(schema: Schema, obj: any, writer: BinaryWriter) { + if (typeof obj.borshSerialize === 'function') { + obj.borshSerialize(writer); + return; + } const structSchema = schema.get(obj.constructor); if (!structSchema) { throw new BorshError(`Class ${obj.constructor.name} is missing in schema`); @@ -343,6 +347,10 @@ function deserializeField(schema: Schema, fieldName: string, fieldType: any, rea } function deserializeStruct(schema: Schema, classType: any, reader: BinaryReader) { + if (typeof classType.borshDeserialize === 'function') { + return classType.borshDeserialize(reader); + } + const structSchema = schema.get(classType); if (!structSchema) { throw new BorshError(`Class ${classType.name} is missing in schema`); diff --git a/borsh-ts/test/serialize.test.js b/borsh-ts/test/serialize.test.js index 9e7dcd7b..460b95ae 100644 --- a/borsh-ts/test/serialize.test.js +++ b/borsh-ts/test/serialize.test.js @@ -11,6 +11,20 @@ class Assignable { class Test extends Assignable { } +class Serializable { + constructor(data) { + this.data = data; + } + + static borshDeserialize(reader) { + return new Serializable(reader.readU8()); + } + + borshSerialize(writer) { + writer.writeU8(this.data); + } +} + test('serialize object', async () => { const value = new Test({ x: 255, y: 20, z: '123', q: [1, 2, 3] }); const schema = new Map([[Test, { kind: 'struct', fields: [['x', 'u8'], ['y', 'u64'], ['z', 'string'], ['q', [3]]] }]]); @@ -68,6 +82,15 @@ test('serialize max uint', async () => { expect(newValue.t.toString()).toEqual('13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095'); }); +test('serialize/deserialize with class methods', () => { + const item = new Serializable(10); + + const buf = borsh.serialize(null, item); + const newValue = borsh.deserialize(null, Serializable, buf); + + expect(newValue).toEqual(item); +}); + test('baseEncode string test', async () => { const encodedValue = borsh.baseEncode("244ZQ9cgj3CQ6bWBdytfrJMuMQ1jdXLFGnr4HhvtCTnM"); const expectedValue = "HKk9gqNj4xb4rLdJuzT5zzJbLa4vHBdYCxQT9H99csQh6nz3Hfpqn4jtWA92"; diff --git a/lib/index.js b/lib/index.js index c3447567..b6682a14 100644 --- a/lib/index.js +++ b/lib/index.js @@ -291,6 +291,10 @@ function serializeField(schema, fieldName, value, fieldType, writer) { } } function serializeStruct(schema, obj, writer) { + if (typeof obj.borshSerialize === 'function') { + obj.borshSerialize(writer); + return; + } const structSchema = schema.get(obj.constructor); if (!structSchema) { throw new BorshError(`Class ${obj.constructor.name} is missing in schema`); @@ -351,6 +355,9 @@ function deserializeField(schema, fieldName, fieldType, reader) { } } function deserializeStruct(schema, classType, reader) { + if (typeof classType.borshDeserialize === 'function') { + return classType.borshDeserialize(reader); + } const structSchema = schema.get(classType); if (!structSchema) { throw new BorshError(`Class ${classType.name} is missing in schema`); diff --git a/package.json b/package.json index 89fd9396..311efd3f 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "devDependencies": { "@types/babel__core": "^7.1.2", "@types/babel__template": "^7.0.2", + "@types/bn.js": "^5.1.0", "@types/node": "^12.7.3", "@typescript-eslint/eslint-plugin": "^2.18.0", "@typescript-eslint/parser": "^2.18.0", @@ -45,8 +46,7 @@ "typescript": "^3.6.2" }, "dependencies": { - "@types/bn.js": "^4.11.5", - "bn.js": "^5.0.0", + "bn.js": "^5.2.0", "bs58": "^4.0.0", "text-encoding-utf-8": "^1.0.2" }