Skip to content

Support COption Layout #243

@smehraein

Description

@smehraein

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions