From 99b2ef7462104f1c5a606a05b874e1f371f57db5 Mon Sep 17 00:00:00 2001 From: Kyle Espinola Date: Mon, 4 Mar 2024 15:16:26 +0100 Subject: [PATCH] refactor: which to try from trait for doing struct conversion --- .../src/deserializer/solana.rs | 254 +++++++++++------- 1 file changed, 152 insertions(+), 102 deletions(-) diff --git a/plerkle_serialization/src/deserializer/solana.rs b/plerkle_serialization/src/deserializer/solana.rs index ec2f6ea..625b93d 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,81 +21,81 @@ 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) -} +pub struct SolanaPubkey(pub Pubkey); -pub fn parse_slice(data: Option>) -> SolanaDeserializeResult<&[u8]> { - Ok(data.ok_or(SolanaDeserializerError::NotFound)?.bytes()) +impl TryFrom> for SolanaPubkey { + type Error = SolanaDeserializerError; + + fn try_from(pubkey: Option<&FBPubkey>) -> SolanaDeserializeResult { + Ok(Self( + Pubkey::try_from( + pubkey + .ok_or(SolanaDeserializerError::NotFound)? + .0 + .as_slice(), + ) + .map_err(|_error| SolanaDeserializerError::InvalidFlatBufferKey)?, + )) + } } -pub fn parse_signature(data: Option<&str>) -> SolanaDeserializeResult { - data.ok_or(SolanaDeserializerError::NotFound)? - .parse() - .map_err(|_error| SolanaDeserializerError::DeserializationError) +pub struct SolanaDataSlice<'a>(pub &'a [u8]); + +impl<'a> TryFrom>> for SolanaDataSlice<'a> { + type Error = SolanaDeserializerError; + + fn try_from(data: Option>) -> SolanaDeserializeResult { + Ok(Self(data.ok_or(SolanaDeserializerError::NotFound)?.bytes())) + } } -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 SolanaSignature(pub Signature); + +impl TryFrom> for SolanaSignature { + type Error = SolanaDeserializerError; + + fn try_from(data: Option<&str>) -> SolanaDeserializeResult { + Ok(Self( + data.ok_or(SolanaDeserializerError::NotFound)? + .parse::() + .map_err(|_error| SolanaDeserializerError::DeserializationError)?, + )) + } } -pub fn parse_compiled_instructions( - vec_cix: Option>>, -) -> SolanaDeserializeResult> { - let mut message_instructions = vec![]; - - if let Some(vec_cix) = vec_cix { - for cix in vec_cix { - message_instructions.push(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(), +pub struct SolanaPubkeys(pub Vec); + +impl TryFrom>> for SolanaPubkeys { + type Error = SolanaDeserializerError; + + fn try_from(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::>>() + .map(SolanaPubkeys) } - - Ok(message_instructions) } -pub fn parse_compiled_inner_instructions( - vec_ixs: Vector<'_, ForwardsUOffset>, -) -> SolanaDeserializeResult> { - let mut meta_inner_instructions = vec![]; +pub struct SolanaCompiledInstructions(pub Vec); - 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 { +impl<'a> TryFrom>>>> + for SolanaCompiledInstructions +{ + type Error = SolanaDeserializerError; + + fn try_from( + vec_cix: Option>>>, + ) -> SolanaDeserializeResult { + let mut message_instructions = vec![]; + + if let Some(vec_cix) = vec_cix { + for cix in vec_cix { + message_instructions.push(CompiledInstruction { program_id_index: cix.program_id_index(), accounts: cix .accounts() @@ -105,52 +107,100 @@ pub fn parse_compiled_inner_instructions( .ok_or(SolanaDeserializerError::NotFound)? .bytes() .to_vec(), - }, - stack_height: Some(ix.stack_height() as u32), - }); + }) + } } - meta_inner_instructions.push(InnerInstructions { - index: ixs.index(), - instructions, - }) - } - Ok(meta_inner_instructions) + Ok(Self(message_instructions)) + } } -pub fn parse_inner_instructions( - vec_ixs: Vector<'_, ForwardsUOffset>, -) -> SolanaDeserializeResult> { - vec_ixs - .iter() - .map(|iixs| { - let instructions = iixs +pub struct SolanaInnerInstructions(pub Vec); + +impl<'a> TryFrom>>> + for SolanaInnerInstructions +{ + type Error = SolanaDeserializerError; + + fn try_from( + vec_ixs: Vector<'_, ForwardsUOffset>>, + ) -> SolanaDeserializeResult { + let mut meta_inner_instructions = vec![]; + + for ixs in vec_ixs { + let mut instructions = vec![]; + for ix in ixs .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), + { + 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, + }) + } + + Ok(Self(meta_inner_instructions)) + } +} + +impl<'a> TryFrom>>> for SolanaInnerInstructions { + type Error = SolanaDeserializerError; + + fn try_from( + 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), + }) }) + .collect::>>()?; + Ok(InnerInstructions { + index: iixs.index(), + instructions, }) - .collect::>>()?; - Ok(InnerInstructions { - index: iixs.index(), - instructions, }) - }) - .collect::>>() + .collect::>>() + .map(SolanaInnerInstructions) + } }