-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to serialize Enum? #21
Comments
Similarly I would like to serialize an array of some type but its fails with error Class array is missing in schema |
|
In javascript? What would be a vector? |
You can convert an enum array into number array, then new Uint8Array(enumNumber_array); |
good news.. I think I figured it out. But here it goes. Step 1: serialize the enum variant you want to send (on its own). In my case it was a struct:
so I serialized it as a class:
Step 2: create a class with your instructions. Like the name suggests we'll be passing in serialized versions of our enum variants later on.
Step 3: serialize the instruction.
The above successfully works with this on the rust end:
Like I said.. it ain't pretty. I basically reverse engineered from the library code. If one of the maintainers could comment with a better solution that would be awesome. |
A slightly hackier version of the above looks like this:
This also works. The important part here is the values array - we must pass in our serialized enum variant as i'th item into the array, where i = matches enum in rust. So eg in my case I had 5 variants in my rust enum and I wanted to trigger the 5th. So I pased in the data as the 5th item into the array on js end. This is because we basically need borsh to insert "4" (5th item starting from 0) as the first byte into the byte array it sends to the program. Not sure if better or worse approach. |
Coming back to this some time later... there's a far easier solution that I can now see: // 1)
const empty_schema = new Map([[Empty, {kind: 'struct', fields: [['number', 'u32']]}]]);
const empty_size = borsh.serialize(empty_schema, new Empty()).length;
const empty_serialized = borsh.serialize(empty_schema, new Empty({number: 5}));
// 2) In my case the instruction is the 5th in order
const data = Buffer.from(Uint8Array.of(4, ...empty_serialized)) Might not work for all use-cases, but for instructions this seems superiod to what I suggested above. |
I made a draft PR #39, that could make this a bit cleaner. What we could do with it @Variant(4)
class Empty {
@Field({ type: 'i32' })
number = 0;
constructor(fields) {
if (fields) {
this.number = fields.number;
}
}
}
const generatedSchemas = generateSchema([Empty])
const buf = serialize(generatedSchemas, new Empty({number: 5})); Variant(4) means instruction is the 5th in order |
It would be great if PR39 got reviewed and merged soon. It should be much more straight-forward to serialize enums. It would be much appreciated! |
There has been no activity by the code maintainers since my last post. As I need these changes for my own project (which is "enum heavy") I started to maintain my own fork in the mean time. https://github.com/dao-xyz/borsh-ts I also added the support for enum deserialization. See this test. class Super {}
@variant(0)
class Enum0 extends Super {
@field({ type: "u8" })
public a: number;
constructor(a: number) {
super();
this.a = a;
}
}
@variant(1)
class Enum1 extends Super {
@field({ type: "u8" })
public b: number;
constructor(b: number) {
super();
this.b = b;
}
}
class TestStruct {
@field({ type: Super })
public enum: Super;
constructor(value: Super) {
this.enum = value;
}
}
const instance = new TestStruct(new Enum1(4));
const serialized = serialize(instance);
expect(serialized).toEqual(Buffer.from([1, 4]));
const deserialized = deserialize(
Buffer.from(serialized),
TestStruct,
);
expect(deserialized.enum).toBeInstanceOf(Enum1);
expect((deserialized.enum as Enum1).b).toEqual(4); Feel free to use it if you find it useful. |
Many thanks! I hope the PR gets merged soon :) |
should be fixed now, please open again if not |
I haven't found any example to to serialize an enum. Can you please give an example to to do it. For example, here is a Rust enum:
The text was updated successfully, but these errors were encountered: