ingest 0.1.1

Single and multi-threaded custom ingestion crate for Stellar Futurenet, written in Rust.
Documentation
use stellar_xdr::next::{LedgerCloseMeta, TransactionEnvelope, GeneralizedTransactionSet, TransactionPhase, TxSetComponent, TransactionResultMeta, SorobanTransactionMeta, TransactionMeta, ContractEvent};

use crate::{MetaResult, BufReaderError};

#[derive(thiserror::Error, Debug, Clone)]
pub enum ReaderError {
    #[error("Error while reading meta result {0}")]
    MetaResult(BufReaderError)

}

pub struct LedgerCloseMetaReader;

impl LedgerCloseMetaReader {

    pub fn ledegr_sequence(result: &MetaResult) -> Result<u32, ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.ledger_header.header.ledger_seq)
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.ledger_header.header.ledger_seq)
            }
            
        }
    }

    pub fn ledger_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.ledger_header.hash.0)
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.ledger_header.hash.0)
            }
            
        }
    }

    pub fn previous_ledger_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.ledger_header.header.previous_ledger_hash.0)
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.ledger_header.header.previous_ledger_hash.0)
            }
            
        }
    }

    pub fn protocol_version(result: &MetaResult) -> Result<u32, ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.ledger_header.header.ledger_version)
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.ledger_header.header.ledger_version)
            }
           
        }
    }

    pub fn bucket_list_hash(result: &MetaResult) -> Result<[u8; 32], ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.ledger_header.header.bucket_list_hash.0)
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.ledger_header.header.bucket_list_hash.0)
            }
           
        }
    }

    pub fn count_transactions(result: &MetaResult) -> Result<usize, ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => {
                Ok(v0.tx_processing.len())
            }
            LedgerCloseMeta::V1(v1) => {
                Ok(v1.tx_processing.len())
            }
          
        }
    }

    pub fn transaction_envelopes(result: &MetaResult) -> Result<Vec<TransactionEnvelope>, ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => Ok(v0.tx_set.txs.to_vec()),
            LedgerCloseMeta::V1(v1) => {
                let mut envelopes = Vec::with_capacity(Self::count_transactions(result)?);
                 
                match &v1.tx_set {
                    GeneralizedTransactionSet::V1(v1) => {
                        for phase in v1.phases.iter() {
                            match phase {
                                TransactionPhase::V0(v0) => {
                                    for component in v0.iter() {
                                        match component {
                                            TxSetComponent::TxsetCompTxsMaybeDiscountedFee(txset) => {
                                                envelopes.append(&mut txset.txs.to_vec())
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    
                }
                Ok(envelopes)
            }
          
        }
    }

    pub fn transaction_metas(result: &MetaResult) -> Result<Vec<TransactionResultMeta>, ReaderError> {
        let meta = MetaResultReader::read_meta(result)?;

        match meta {
            LedgerCloseMeta::V0(v0) => Ok(v0.tx_processing.to_vec()),
            LedgerCloseMeta::V1(v1) => Ok(v1.tx_processing.to_vec()),
        }
    }

    pub fn soroban_metas(result: &MetaResult) -> Result<Vec<SorobanTransactionMeta>, ReaderError> {
        let mut soroban_metas = Vec::new();

                for result_meta in Self::transaction_metas(result)? {
                    match result_meta.tx_apply_processing {
                        TransactionMeta::V0(_) => {
                            ()
                        }

                        TransactionMeta::V1(_) => {
                            ()
                        }

                        TransactionMeta::V2(_) => {
                            ()
                        }

                        TransactionMeta::V3(v3) => {
                            if let Some(soroban_meta) = v3.soroban_meta {
                                soroban_metas.push(soroban_meta)
                            }
                        }
                    }
                }

        Ok(soroban_metas)
    }

    pub fn soroban_events(result: &MetaResult) -> Result<Vec<ContractEvent>, ReaderError> {
        let soroban_metas = Self::soroban_metas(result)?;
        let mut contract_events = Vec::new();
        for meta in soroban_metas {
            contract_events.append(&mut meta.events.to_vec())
        }

        Ok(contract_events)
    }

}

pub struct MetaResultReader;

impl MetaResultReader {
    pub fn read_meta(result: &MetaResult) -> Result<&LedgerCloseMeta, ReaderError> {
        if let Some(meta) = &result.ledger_close_meta {
            Ok(&meta.ledger_close_meta)
        } else {
            Err(ReaderError::MetaResult(result.err.clone().unwrap()))
        }
    }
}