Skip to content
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

Support COption Layout #243

Open
smehraein opened this issue Jul 26, 2022 · 0 comments
Open

Support COption Layout #243

smehraein opened this issue Jul 26, 2022 · 0 comments

Comments

@smehraein
Copy link

Would like to add support for Coption encoding/decoding for interacting with accounts using fields of that type. Requires a new layout class in borsh/src/index.ts

Code would look like this:

class CoptionLayout<T> extends LayoutCls<T | null> {
  layout: Layout<T>;
  discriminator: Layout<number>;

  constructor(layout: Layout<T>, property?: string) {
    super(-1, property);
    this.layout = layout;
    this.discriminator = u32();
  }

  encode(src: T | null, b: Buffer, offset = 0): number {
    if (src === null || src === undefined) {
      return this.discriminator.encode(0, b, offset);
    }
    this.discriminator.encode(4, b, offset);
    return this.layout.encode(src, b, offset + 4) + 4;
  }

  decode(b: Buffer, offset = 0): T | null {
    const discriminator = this.discriminator.decode(b, offset);
    if (discriminator === 0) {
      return null;
    } else if (discriminator >= 1) {
      return this.layout.decode(b, offset + 4);
    }
    throw new Error('Invalid coption ' + this.property);
  }

  getSpan(b: Buffer, offset = 0): number {
    const discriminator = this.discriminator.decode(b, offset);
    if (discriminator === 0) {
      return 4;
    } else if (discriminator >= 1) {
      return this.layout.getSpan(b, offset + 4) + 4;
    }
    throw new Error('Invalid coption ' + this.property);
  }
}

export function coption<T>(
  layout: Layout<T>,
  property?: string
): Layout<T | null> {
  return new CoptionLayout<T>(layout, property);
}

Happy to create the PR myself. Just let me know if the team supports adding this. Already using a jerry-rigged version of this for my own codebase.

Only question is around else if (discriminator >= 1). I believe that the coption would also evaluate to 1 if it's set, but I'm not 100% sure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant