Repository: MystenLabs/sui
File: crates/sui-indexer-alt/src/handlers/tx_balance_changes.rs (Rust)

Code before:
            *changes
                .entry((object.owner().clone(), type_))
                .or_insert(0i128) -= balance as i128;
        }
    }

    for object in transaction.output_objects(&checkpoint.object_set) {
        if let Some((type_, balance)) = Coin::extract_balance_if_coin(object)? {
            *changes
                .entry((object.owner().clone(), type_))
                .or_insert(0i128) += balance as i128;
        }
    }

    Ok(changes
        .into_iter()
        .filter_map(|((owner, coin_type), amount)| {
            if amount == 0 {
                None
            } else {
                Some(BalanceChange::V1 {
                    owner,
                    coin_type: coin_type.to_canonical_string(/* with_prefix */ true),
                    amount,
                })
            }
        })
        .collect())
}

#[cfg(test)]
mod tests {
    use diesel_async::RunQueryDsl;
    use sui_indexer_alt_framework::Indexer;
    use sui_indexer_alt_framework::types::test_checkpoint_data_builder::TestCheckpointBuilder;
    use sui_indexer_alt_schema::MIGRATIONS;

    use crate::handlers::cp_sequence_numbers::CpSequenceNumbers;

    use super::*;

    async fn get_all_tx_balance_changes(conn: &mut Connection<'_>) -> Result<Vec<i64>> {
        Ok(tx_balance_changes::table
            .select(tx_balance_changes::tx_sequence_number)
            .order_by(tx_balance_changes::tx_sequence_number)
            .load(conn)
            .await?)
    }

    #[tokio::test]
    async fn test_tx_balance_changes_pruning_complains_if_no_mapping() {

Review comment (suggestion):
nit: this is another opportunity for `.then`:


```suggestion
            (amount > 0).then(|| BalanceChange::V1 {
                owner,
                coin_type: coin_type.to_canonical_string(/* with_prefix */ true),
                amount,
            })
```

Code after:
            *changes
                .entry((object.owner().clone(), type_))
                .or_insert(0i128) -= balance as i128;
        }
    }

    for object in transaction.output_objects(&checkpoint.object_set) {
        if let Some((type_, balance)) = Coin::extract_balance_if_coin(object)? {
            *changes
                .entry((object.owner().clone(), type_))
                .or_insert(0i128) += balance as i128;
        }
    }

    Ok(changes
        .into_iter()
        .filter_map(|((owner, coin_type), amount)| {
            (amount != 0).then(|| BalanceChange::V1 {
                owner,
                coin_type: coin_type.to_canonical_string(/* with_prefix */ true),
                amount,
            })
        })
        .collect())
}

#[cfg(test)]
mod tests {
    use diesel_async::RunQueryDsl;
    use sui_indexer_alt_framework::Indexer;
    use sui_indexer_alt_framework::types::test_checkpoint_data_builder::TestCheckpointBuilder;
    use sui_indexer_alt_schema::MIGRATIONS;

    use crate::handlers::cp_sequence_numbers::CpSequenceNumbers;

    use super::*;

    async fn get_all_tx_balance_changes(conn: &mut Connection<'_>) -> Result<Vec<i64>> {
        Ok(tx_balance_changes::table
            .select(tx_balance_changes::tx_sequence_number)
            .order_by(tx_balance_changes::tx_sequence_number)
            .load(conn)
            .await?)
    }

    #[tokio::test]
    async fn test_tx_balance_changes_pruning_complains_if_no_mapping() {
        let (indexer, _db) = Indexer::new_for_testing(&MIGRATIONS).await;
        let mut conn = indexer.store().connect().await.unwrap();

        let result = TxBalanceChanges.prune(0, 2, &mut conn).await;