-
Notifications
You must be signed in to change notification settings - Fork 915
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(experimental): allow variable-size number codecs in getBoole…
…anCodec
- Loading branch information
1 parent
164e455
commit e345282
Showing
4 changed files
with
100 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@solana/codecs-data-structures': patch | ||
--- | ||
|
||
The `getBooleanCodec` function now accepts variable-size number codecs |
96 changes: 68 additions & 28 deletions
96
packages/codecs-data-structures/src/__tests__/boolean-test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,76 @@ | ||
import { mapCodec } from '@solana/codecs-core'; | ||
import { getShortU16Codec, getU32Codec } from '@solana/codecs-numbers'; | ||
import { SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH, SolanaError } from '@solana/errors'; | ||
|
||
import { getBooleanCodec } from '../boolean'; | ||
import { b } from './__setup__'; | ||
|
||
describe('getBooleanCodec', () => { | ||
const boolean = getBooleanCodec; | ||
const u32 = getU32Codec; | ||
|
||
it('encodes booleans', () => { | ||
// Encode. | ||
expect(boolean().encode(true)).toStrictEqual(b('01')); | ||
expect(boolean().encode(false)).toStrictEqual(b('00')); | ||
expect(boolean({ size: u32() }).encode(true)).toStrictEqual(b('01000000')); | ||
expect(boolean({ size: u32() }).encode(false)).toStrictEqual(b('00000000')); | ||
|
||
// Decode. | ||
expect(boolean().read(b('01'), 0)).toStrictEqual([true, 1]); | ||
expect(boolean().read(b('00'), 0)).toStrictEqual([false, 1]); | ||
expect(boolean().read(b('ffff01'), 2)).toStrictEqual([true, 3]); | ||
expect(boolean().read(b('ffff00'), 2)).toStrictEqual([false, 3]); | ||
expect(boolean({ size: u32() }).read(b('01000000'), 0)).toStrictEqual([true, 4]); | ||
expect(boolean({ size: u32() }).read(b('00000000'), 0)).toStrictEqual([false, 4]); | ||
|
||
// Fails if the codec is not fixed size. | ||
expect(() => boolean({ size: getShortU16Codec() })).toThrow( | ||
new SolanaError(SOLANA_ERROR__CODECS__EXPECTED_FIXED_LENGTH), | ||
); | ||
}); | ||
|
||
it('has the right sizes', () => { | ||
expect(boolean().fixedSize).toBe(1); | ||
expect(boolean({ size: u32() }).fixedSize).toBe(4); | ||
// A variable-size number codecs that uses 0 for `false` | ||
// and the max shortU16 value for `true`. | ||
const mappedShortU16 = mapCodec( | ||
getShortU16Codec(), | ||
// eslint-disable-next-line jest/no-conditional-in-test | ||
v => (v === 0 ? 0 : 0xffff), | ||
// eslint-disable-next-line jest/no-conditional-in-test | ||
v => (v === 0 ? 0 : 1), | ||
); | ||
|
||
it('encodes booleans using a u8 number', () => { | ||
expect(getBooleanCodec().encode(true)).toStrictEqual(b('01')); | ||
expect(getBooleanCodec().encode(false)).toStrictEqual(b('00')); | ||
}); | ||
|
||
it('decodes booleans using a u8 number', () => { | ||
expect(getBooleanCodec().decode(b('01'))).toBe(true); | ||
expect(getBooleanCodec().decode(b('00'))).toBe(false); | ||
}); | ||
|
||
it('encodes booleans using a custom fixed-size number codec', () => { | ||
const codec = getBooleanCodec({ size: getU32Codec() }); | ||
expect(codec.encode(true)).toStrictEqual(b('01000000')); | ||
expect(codec.encode(false)).toStrictEqual(b('00000000')); | ||
}); | ||
|
||
it('decodes booleans using a custom fixed-size number codec', () => { | ||
const codec = getBooleanCodec({ size: getU32Codec() }); | ||
expect(codec.decode(b('01000000'))).toBe(true); | ||
expect(codec.decode(b('00000000'))).toBe(false); | ||
}); | ||
|
||
it('encodes booleans using a custom variable-size number codec', () => { | ||
const codec = getBooleanCodec({ size: mappedShortU16 }); | ||
expect(codec.encode(true)).toStrictEqual(b('ffff03')); | ||
expect(codec.encode(false)).toStrictEqual(b('00')); | ||
}); | ||
|
||
it('decodes booleans using a custom variable-size number codec', () => { | ||
const codec = getBooleanCodec({ size: mappedShortU16 }); | ||
expect(codec.decode(b('ffff03'))).toBe(true); | ||
expect(codec.decode(b('00'))).toBe(false); | ||
}); | ||
|
||
it('pushes the offset forward when writing', () => { | ||
expect(getBooleanCodec().write(true, new Uint8Array(10), 6)).toBe(7); | ||
}); | ||
|
||
it('pushes the offset forward when reading', () => { | ||
expect(getBooleanCodec().read(b('ffff00'), 2)).toStrictEqual([false, 3]); | ||
}); | ||
|
||
it('returns the correct default fixed size', () => { | ||
const codec = getBooleanCodec(); | ||
expect(codec.fixedSize).toBe(1); | ||
}); | ||
|
||
it('returns the correct custom fixed size', () => { | ||
const codec = getBooleanCodec({ size: getU32Codec() }); | ||
expect(codec.fixedSize).toBe(4); | ||
}); | ||
|
||
it('returns the correct custom variable size', () => { | ||
const codec = getBooleanCodec({ size: mappedShortU16 }); | ||
expect(codec.getSizeFromValue(false)).toBe(1); | ||
expect(codec.getSizeFromValue(true)).toBe(3); | ||
expect(codec.maxSize).toBe(3); | ||
}); | ||
}); |
24 changes: 19 additions & 5 deletions
24
packages/codecs-data-structures/src/__typetests__/boolean-typetest.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,39 @@ | ||
import { Codec, Decoder, Encoder, FixedSizeCodec, FixedSizeDecoder, FixedSizeEncoder } from '@solana/codecs-core'; | ||
import { getU32Codec, getU32Decoder, getU32Encoder } from '@solana/codecs-numbers'; | ||
import { | ||
FixedSizeCodec, | ||
FixedSizeDecoder, | ||
FixedSizeEncoder, | ||
VariableSizeCodec, | ||
VariableSizeDecoder, | ||
VariableSizeEncoder, | ||
} from '@solana/codecs-core'; | ||
import { | ||
getShortU16Codec, | ||
getShortU16Decoder, | ||
getShortU16Encoder, | ||
getU32Codec, | ||
getU32Decoder, | ||
getU32Encoder, | ||
} from '@solana/codecs-numbers'; | ||
|
||
import { getBooleanCodec, getBooleanDecoder, getBooleanEncoder } from '../boolean'; | ||
|
||
{ | ||
// [getBooleanEncoder]: It knows if the encoder is fixed size or variable size. | ||
getBooleanEncoder() satisfies FixedSizeEncoder<boolean, 1>; | ||
getBooleanEncoder({ size: getU32Encoder() }) satisfies FixedSizeEncoder<boolean, 4>; | ||
getBooleanEncoder({ size: {} as Encoder<number> }) satisfies Encoder<boolean>; | ||
getBooleanEncoder({ size: getShortU16Encoder() }) satisfies VariableSizeEncoder<boolean>; | ||
} | ||
|
||
{ | ||
// [getBooleanDecoder]: It knows if the decoder is fixed size or variable size. | ||
getBooleanDecoder() satisfies FixedSizeDecoder<boolean, 1>; | ||
getBooleanDecoder({ size: getU32Decoder() }) satisfies FixedSizeDecoder<boolean, 4>; | ||
getBooleanDecoder({ size: {} as Decoder<number> }) satisfies Decoder<boolean>; | ||
getBooleanDecoder({ size: getShortU16Decoder() }) satisfies VariableSizeDecoder<boolean>; | ||
} | ||
|
||
{ | ||
// [getBooleanCodec]: It knows if the codec is fixed size or variable size. | ||
getBooleanCodec() satisfies FixedSizeCodec<boolean, boolean, 1>; | ||
getBooleanCodec({ size: getU32Codec() }) satisfies FixedSizeCodec<boolean, boolean, 4>; | ||
getBooleanCodec({ size: {} as Codec<number> }) satisfies Codec<boolean>; | ||
getBooleanCodec({ size: getShortU16Codec() }) satisfies VariableSizeCodec<boolean>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters