pub fn has_inputs_and_outputs(tx: &Transaction) -> Result<(), TransactionError> {
    // The consensus rule is written in terms of numbers, but our transactions
    // hold enum'd data. Mixing pattern matching and numerical checks is risky,
    // so convert everything to counts and sum up.
    match tx {
        Transaction::V4 {
            inputs,
            outputs,
            joinsplit_data,
            sapling_shielded_data,
            ..
        } => {
            let tx_in_count = inputs.len();
            let tx_out_count = outputs.len();
            let n_joinsplit = joinsplit_data
                .as_ref()
                .map(|d| d.joinsplits().count())
                .unwrap_or(0);
            let n_shielded_spend = sapling_shielded_data
                .as_ref()
                .map(|d| d.spends().count())
                .unwrap_or(0);
            let n_shielded_output = sapling_shielded_data
                .as_ref()
                .map(|d| d.outputs().count())
                .unwrap_or(0);

            if tx_in_count + n_shielded_spend + n_joinsplit == 0 {
                Err(TransactionError::NoInputs)
            } else if tx_out_count + n_shielded_output + n_joinsplit == 0 {
                Err(TransactionError::NoOutputs)
            } else {
                Ok(())
            }
        }
        Transaction::V1 { .. } | Transaction::V2 { .. } | Transaction::V3 { .. } => {
            unreachable!("tx version is checked first")
        }
        Transaction::V5 { .. } => {
            unimplemented!("v5 transaction format as specified in ZIP-225")
        }
    }
}
/// Checks that the transaction has inputs and outputs.
///
/// More specifically:
///
/// * at least one of tx_in_count, nShieldedSpend, and nJoinSplit MUST be non-zero.
/// * at least one of tx_out_count, nShieldedOutput, and nJoinSplit MUST be non-zero.
///
/// https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus
Checks that the transaction has inputs and outputs.
More specifically.

at least one of tx_in_count, nShieldedSpend, and nJoinSplit MUST be non-zero.
at least one of tx_out_count, nShieldedOutput, and nJoinSplit MUST be non-zero.


Checks that the transaction has inputs and outputs . More specifically . at least one of tx_in_count nShieldedSpend and nJoinSplit MUST be non - zero . at least one of tx_out_count nShieldedOutput and nJoinSplit MUST be non - zero .
pub fn has_inputs_and_outputs(tx: &Transaction) -> Result<(), TransactionError> {
    // The consensus rule is written in terms of numbers, but our transactions
    // hold enum'd data. Mixing pattern matching and numerical checks is risky,
    // so convert everything to counts and sum up.
    match tx {
        Transaction::V4 {
            inputs,
            outputs,
            joinsplit_data,
            sapling_shielded_data,
            ..
        } => {
            let tx_in_count = inputs.len();
            let tx_out_count = outputs.len();
            let n_joinsplit = joinsplit_data
                .as_ref()
                .map(|d| d.joinsplits().count())
                .unwrap_or(0);
            let n_shielded_spend = sapling_shielded_data
                .as_ref()
                .map(|d| d.spends().count())
                .unwrap_or(0);
            let n_shielded_output = sapling_shielded_data
                .as_ref()
                .map(|d| d.outputs().count())
                .unwrap_or(0);
            if tx_in_count + n_shielded_spend + n_joinsplit == 0 {
                Err(TransactionError::NoInputs)
            } else if tx_out_count + n_shielded_output + n_joinsplit == 0 {
                Err(TransactionError::NoOutputs)
            } else {
                Ok(())
            }
        }
        Transaction::V1 { .. } | Transaction::V2 { .. } | Transaction::V3 { .. } => {
            unreachable!("tx version is checked first")
        }
        Transaction::V5 { .. } => {
            unimplemented!("v5 transaction format as specified in ZIP-225")
        }
    }
}
pub fn has_inputs_and_outputs ( tx : & Transaction ) -> Result < ( ) , TransactionError > { // The consensus rule is written in terms of numbers, but our transactions // hold enum'd data. Mixing pattern matching and numerical checks is risky, // so convert everything to counts and sum up. match tx { Transaction :: V4 { inputs , outputs , joinsplit_data , sapling_shielded_data , .. } => { let tx_in_count = inputs . len ( ) ; let tx_out_count = outputs . len ( ) ; let n_joinsplit = joinsplit_data . as_ref ( ) . map ( | d | d . joinsplits ( ) . count ( ) ) . unwrap_or ( 0 ) ; let n_shielded_spend = sapling_shielded_data . as_ref ( ) . map ( | d | d . spends ( ) . count ( ) ) . unwrap_or ( 0 ) ; let n_shielded_output = sapling_shielded_data . as_ref ( ) . map ( | d | d . outputs ( ) . count ( ) ) . unwrap_or ( 0 ) ; if tx_in_count + n_shielded_spend + n_joinsplit == 0 { Err ( TransactionError :: NoInputs ) } else if tx_out_count + n_shielded_output + n_joinsplit == 0 { Err ( TransactionError :: NoOutputs ) } else { Ok ( ( ) ) } } Transaction :: V1 { .. } | Transaction :: V2 { .. } | Transaction :: V3 { .. } => { unreachable ! ( " " ) } Transaction :: V5 { .. } => { unimplemented ! ( " " ) } } }
Checks that the transaction has inputs and outputs.
Checks that the transaction has inputs and outputs .
tx
&Transaction