pub trait TlvState {
// Required method
fn get_data(&self) -> &[u8] ⓘ;
// Provided methods
fn get_value_with_repetition<V: SplDiscriminate + Pod>(
&self,
repetition_number: usize,
) -> Result<&V, ProgramError> { ... }
fn get_first_value<V: SplDiscriminate + Pod>(
&self,
) -> Result<&V, ProgramError> { ... }
fn get_variable_len_value_with_repetition<V: SplDiscriminate + VariableLenPack>(
&self,
repetition_number: usize,
) -> Result<V, ProgramError> { ... }
fn get_first_variable_len_value<V: SplDiscriminate + VariableLenPack>(
&self,
) -> Result<V, ProgramError> { ... }
fn get_bytes_with_repetition<V: SplDiscriminate>(
&self,
repetition_number: usize,
) -> Result<&[u8], ProgramError> { ... }
fn get_first_bytes<V: SplDiscriminate>(&self) -> Result<&[u8], ProgramError> { ... }
fn get_discriminators(
&self,
) -> Result<Vec<ArrayDiscriminator>, ProgramError> { ... }
fn get_base_len() -> usize { ... }
}
Expand description
Trait for all TLV state
Stores data as any number of type-length-value structures underneath, where:
- the “type” is an
ArrayDiscriminator
, 8 bytes - the “length” is a
Length
, 4 bytes - the “value” is a slab of “length” bytes
With this structure, it’s possible to hold onto any number of entries with unique discriminators, provided that the total underlying data has enough bytes for every entry.
For example, if we have two distinct types, one which is an 8-byte array
of value [0, 1, 0, 0, 0, 0, 0, 0]
and discriminator
[1, 1, 1, 1, 1, 1, 1, 1]
, and another which is just a single u8
of value
4
with the discriminator [2, 2, 2, 2, 2, 2, 2, 2]
, we can deserialize
this buffer as follows:
use {
bytemuck::{Pod, Zeroable},
spl_discriminator::{ArrayDiscriminator, SplDiscriminate},
spl_type_length_value::state::{TlvState, TlvStateBorrowed, TlvStateMut},
};
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
struct MyPodValue {
data: [u8; 8],
}
impl SplDiscriminate for MyPodValue {
const SPL_DISCRIMINATOR: ArrayDiscriminator = ArrayDiscriminator::new([1; ArrayDiscriminator::LENGTH]);
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Pod, Zeroable)]
struct MyOtherPodValue {
data: u8,
}
impl SplDiscriminate for MyOtherPodValue {
const SPL_DISCRIMINATOR: ArrayDiscriminator = ArrayDiscriminator::new([2; ArrayDiscriminator::LENGTH]);
}
let buffer = [
1, 1, 1, 1, 1, 1, 1, 1, // first type's discriminator
8, 0, 0, 0, // first type's length
0, 1, 0, 0, 0, 0, 0, 0, // first type's value
2, 2, 2, 2, 2, 2, 2, 2, // second type's discriminator
1, 0, 0, 0, // second type's length
4, // second type's value
];
let state = TlvStateBorrowed::unpack(&buffer).unwrap();
let value = state.get_first_value::<MyPodValue>().unwrap();
assert_eq!(value.data, [0, 1, 0, 0, 0, 0, 0, 0]);
let value = state.get_first_value::<MyOtherPodValue>().unwrap();
assert_eq!(value.data, 4);
See the README and tests for more examples on how to use these types.
Required Methods§
Provided Methods§
Sourcefn get_value_with_repetition<V: SplDiscriminate + Pod>(
&self,
repetition_number: usize,
) -> Result<&V, ProgramError>
fn get_value_with_repetition<V: SplDiscriminate + Pod>( &self, repetition_number: usize, ) -> Result<&V, ProgramError>
Unpack a portion of the TLV data as the desired Pod type for the entry number specified
Sourcefn get_first_value<V: SplDiscriminate + Pod>(&self) -> Result<&V, ProgramError>
fn get_first_value<V: SplDiscriminate + Pod>(&self) -> Result<&V, ProgramError>
Unpack a portion of the TLV data as the desired Pod type for the first entry found
Sourcefn get_variable_len_value_with_repetition<V: SplDiscriminate + VariableLenPack>(
&self,
repetition_number: usize,
) -> Result<V, ProgramError>
fn get_variable_len_value_with_repetition<V: SplDiscriminate + VariableLenPack>( &self, repetition_number: usize, ) -> Result<V, ProgramError>
Unpacks a portion of the TLV data as the desired variable-length type for the entry number specified
Sourcefn get_first_variable_len_value<V: SplDiscriminate + VariableLenPack>(
&self,
) -> Result<V, ProgramError>
fn get_first_variable_len_value<V: SplDiscriminate + VariableLenPack>( &self, ) -> Result<V, ProgramError>
Unpacks a portion of the TLV data as the desired variable-length type for the first entry found
Sourcefn get_bytes_with_repetition<V: SplDiscriminate>(
&self,
repetition_number: usize,
) -> Result<&[u8], ProgramError>
fn get_bytes_with_repetition<V: SplDiscriminate>( &self, repetition_number: usize, ) -> Result<&[u8], ProgramError>
Unpack a portion of the TLV data as bytes for the entry number specified
Sourcefn get_first_bytes<V: SplDiscriminate>(&self) -> Result<&[u8], ProgramError>
fn get_first_bytes<V: SplDiscriminate>(&self) -> Result<&[u8], ProgramError>
Unpack a portion of the TLV data as bytes for the first entry found
Sourcefn get_discriminators(&self) -> Result<Vec<ArrayDiscriminator>, ProgramError>
fn get_discriminators(&self) -> Result<Vec<ArrayDiscriminator>, ProgramError>
Iterates through the TLV entries, returning only the types
Sourcefn get_base_len() -> usize
fn get_base_len() -> usize
Get the base size required for TLV data
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.