diff --git a/plerkle_serialization/src/deserializer/solana.rs b/plerkle_serialization/src/deserializer/solana.rs index ec2f6ea..9d062a5 100644 --- a/plerkle_serialization/src/deserializer/solana.rs +++ b/plerkle_serialization/src/deserializer/solana.rs @@ -1,3 +1,5 @@ +use std::convert::TryFrom; + use crate::{ CompiledInnerInstructions as FBCompiledInnerInstructions, CompiledInstruction as FBCompiledInstruction, InnerInstructions as FBInnerInstructions, @@ -19,46 +21,67 @@ pub enum SolanaDeserializerError { pub type SolanaDeserializeResult = Result; -pub fn parse_pubkey(pubkey: Option<&FBPubkey>) -> SolanaDeserializeResult { - Pubkey::try_from( - pubkey - .ok_or(SolanaDeserializerError::NotFound)? - .0 - .as_slice(), - ) - .map_err(|_error| SolanaDeserializerError::InvalidFlatBufferKey) +impl<'a> TryFrom<&FBPubkey> for Pubkey { + type Error = SolanaDeserializerError; + + fn try_from(pubkey: &FBPubkey) -> SolanaDeserializeResult { + Pubkey::try_from(pubkey.0.as_slice()) + .map_err(|_error| SolanaDeserializerError::InvalidFlatBufferKey) + } } -pub fn parse_slice(data: Option>) -> SolanaDeserializeResult<&[u8]> { - Ok(data.ok_or(SolanaDeserializerError::NotFound)?.bytes()) +pub struct PlerkleOptionalU8Vector<'a>(pub Option>); + +impl<'a> TryFrom> for &'a [u8] { + type Error = SolanaDeserializerError; + + fn try_from(data: PlerkleOptionalU8Vector<'a>) -> SolanaDeserializeResult { + Ok(data.0.ok_or(SolanaDeserializerError::NotFound)?.bytes()) + } } -pub fn parse_signature(data: Option<&str>) -> SolanaDeserializeResult { - data.ok_or(SolanaDeserializerError::NotFound)? - .parse() - .map_err(|_error| SolanaDeserializerError::DeserializationError) +pub struct PlerkleOptionalStr<'a>(pub Option<&'a str>); + +impl<'a> TryFrom> for Signature { + type Error = SolanaDeserializerError; + + fn try_from(data: PlerkleOptionalStr<'a>) -> SolanaDeserializeResult { + data.0 + .ok_or(SolanaDeserializerError::NotFound)? + .parse::() + .map_err(|_error| SolanaDeserializerError::DeserializationError) + } } -pub fn parse_account_keys( - public_keys: Option>, -) -> SolanaDeserializeResult> { - public_keys - .ok_or(SolanaDeserializerError::NotFound)? - .iter() - .map(|key| { - Pubkey::try_from(key.0.as_slice()) - .map_err(|_error| SolanaDeserializerError::InvalidFlatBufferKey) - }) - .collect::>>() +pub struct PlerkleOptionalPubkeyVector<'a>(pub Option>); + +impl<'a> TryFrom> for Vec { + type Error = SolanaDeserializerError; + + fn try_from(public_keys: PlerkleOptionalPubkeyVector<'a>) -> SolanaDeserializeResult { + public_keys + .0 + .ok_or(SolanaDeserializerError::NotFound)? + .iter() + .map(|key| { + Pubkey::try_from(key.0.as_slice()) + .map_err(|_error| SolanaDeserializerError::InvalidFlatBufferKey) + }) + .collect::>>() + } } -pub fn parse_compiled_instructions( - vec_cix: Option>>, -) -> SolanaDeserializeResult> { - let mut message_instructions = vec![]; +pub struct PlerkleCompiledInstructionVector<'a>( + pub Vector<'a, ForwardsUOffset>>, +); + +impl<'a> TryFrom> for Vec { + type Error = SolanaDeserializerError; - if let Some(vec_cix) = vec_cix { - for cix in vec_cix { + fn try_from(vec_cix: PlerkleCompiledInstructionVector<'a>) -> SolanaDeserializeResult { + let mut message_instructions = vec![]; + + for cix in vec_cix.0 { message_instructions.push(CompiledInstruction { program_id_index: cix.program_id_index(), accounts: cix @@ -73,84 +96,96 @@ pub fn parse_compiled_instructions( .to_vec(), }) } - } - Ok(message_instructions) + Ok(message_instructions) + } } -pub fn parse_compiled_inner_instructions( - vec_ixs: Vector<'_, ForwardsUOffset>, -) -> SolanaDeserializeResult> { - let mut meta_inner_instructions = vec![]; +pub struct PlerkleCompiledInnerInstructionVector<'a>( + pub Vector<'a, ForwardsUOffset>>, +); +impl<'a> TryFrom> for Vec { + type Error = SolanaDeserializerError; - for ixs in vec_ixs { - let mut instructions = vec![]; - for ix in ixs - .instructions() - .ok_or(SolanaDeserializerError::NotFound)? - { - let cix = ix - .compiled_instruction() - .ok_or(SolanaDeserializerError::NotFound)?; - instructions.push(InnerInstruction { - instruction: CompiledInstruction { - program_id_index: cix.program_id_index(), - accounts: cix - .accounts() - .ok_or(SolanaDeserializerError::NotFound)? - .bytes() - .to_vec(), - data: cix - .data() - .ok_or(SolanaDeserializerError::NotFound)? - .bytes() - .to_vec(), - }, - stack_height: Some(ix.stack_height() as u32), - }); + fn try_from( + vec_ixs: PlerkleCompiledInnerInstructionVector<'a>, + ) -> SolanaDeserializeResult { + let mut meta_inner_instructions = vec![]; + + for ixs in vec_ixs.0 { + let mut instructions = vec![]; + for ix in ixs + .instructions() + .ok_or(SolanaDeserializerError::NotFound)? + { + let cix = ix + .compiled_instruction() + .ok_or(SolanaDeserializerError::NotFound)?; + instructions.push(InnerInstruction { + instruction: CompiledInstruction { + program_id_index: cix.program_id_index(), + accounts: cix + .accounts() + .ok_or(SolanaDeserializerError::NotFound)? + .bytes() + .to_vec(), + data: cix + .data() + .ok_or(SolanaDeserializerError::NotFound)? + .bytes() + .to_vec(), + }, + stack_height: Some(ix.stack_height() as u32), + }); + } + meta_inner_instructions.push(InnerInstructions { + index: ixs.index(), + instructions, + }) } - meta_inner_instructions.push(InnerInstructions { - index: ixs.index(), - instructions, - }) - } - Ok(meta_inner_instructions) + Ok(meta_inner_instructions) + } } -pub fn parse_inner_instructions( - vec_ixs: Vector<'_, ForwardsUOffset>, -) -> SolanaDeserializeResult> { - vec_ixs - .iter() - .map(|iixs| { - let instructions = iixs - .instructions() - .ok_or(SolanaDeserializerError::NotFound)? - .iter() - .map(|cix| { - Ok(InnerInstruction { - instruction: CompiledInstruction { - program_id_index: cix.program_id_index(), - accounts: cix - .accounts() - .ok_or(SolanaDeserializerError::NotFound)? - .bytes() - .to_vec(), - data: cix - .data() - .ok_or(SolanaDeserializerError::NotFound)? - .bytes() - .to_vec(), - }, - stack_height: Some(0), +pub struct PlerkleInnerInstructions<'a>(pub Vector<'a, ForwardsUOffset>>); + +impl<'a> TryFrom> for Vec { + type Error = SolanaDeserializerError; + + fn try_from(vec_ixs: PlerkleInnerInstructions<'a>) -> SolanaDeserializeResult { + vec_ixs + .0 + .iter() + .map(|iixs| { + let instructions = iixs + .instructions() + .ok_or(SolanaDeserializerError::NotFound)? + .iter() + .map(|cix| { + Ok(InnerInstruction { + instruction: CompiledInstruction { + program_id_index: cix.program_id_index(), + accounts: cix + .accounts() + .ok_or(SolanaDeserializerError::NotFound)? + .bytes() + .to_vec(), + data: cix + .data() + .ok_or(SolanaDeserializerError::NotFound)? + .bytes() + .to_vec(), + }, + stack_height: Some(0), + }) }) + .collect::>>()?; + Ok(InnerInstructions { + index: iixs.index(), + instructions, }) - .collect::>>()?; - Ok(InnerInstructions { - index: iixs.index(), - instructions, }) - }) - .collect::>>() + .collect::>>() + } }