hdp_primitives/task/datalake/transactions/
collection.rs

1use std::{fmt::Display, str::FromStr};
2
3use anyhow::{bail, Result};
4use serde::{Deserialize, Serialize};
5
6use crate::task::datalake::{DatalakeCollection, DatalakeField};
7
8use super::{TransactionField, TransactionReceiptField};
9
10pub enum TransactionsCollectionType {
11    Transactions,
12    TransactionReceipts,
13}
14
15impl TransactionsCollectionType {
16    pub fn variants() -> Vec<String> {
17        vec!["TX".to_string(), "TX_RECEIPT".to_string()]
18    }
19}
20
21impl FromStr for TransactionsCollectionType {
22    type Err = anyhow::Error;
23
24    fn from_str(s: &str) -> Result<Self> {
25        match s.to_uppercase().as_str() {
26            "TX" => Ok(TransactionsCollectionType::Transactions),
27            "TX_RECEIPT" => Ok(TransactionsCollectionType::TransactionReceipts),
28            _ => bail!("Unknown transactions collection type"),
29        }
30    }
31}
32
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34#[serde(try_from = "String")]
35pub enum TransactionsCollection {
36    Transactions(TransactionField),
37    TranasactionReceipts(TransactionReceiptField),
38}
39
40impl DatalakeCollection for TransactionsCollection {
41    fn to_index(&self) -> u8 {
42        match self {
43            TransactionsCollection::Transactions(ref field) => field.to_index(),
44            TransactionsCollection::TranasactionReceipts(ref field) => field.to_index(),
45        }
46    }
47
48    fn serialize(&self) -> Result<Vec<u8>> {
49        match self {
50            TransactionsCollection::Transactions(ref field) => Ok([1, field.to_index()].to_vec()),
51            TransactionsCollection::TranasactionReceipts(ref field) => {
52                Ok([2, field.to_index()].to_vec())
53            }
54        }
55    }
56
57    fn deserialize(bytes: &[u8]) -> Result<Self> {
58        if bytes.len() != 2 {
59            return Err(anyhow::Error::msg("Invalid transactions collection"));
60        }
61
62        match bytes[0] {
63            1 => Ok(TransactionsCollection::Transactions(
64                TransactionField::from_index(bytes[1])?,
65            )),
66            2 => Ok(TransactionsCollection::TranasactionReceipts(
67                TransactionReceiptField::from_index(bytes[1])?,
68            )),
69            _ => Err(anyhow::Error::msg("Unknown transactions collection")),
70        }
71    }
72}
73
74impl FromStr for TransactionsCollection {
75    type Err = anyhow::Error;
76
77    fn from_str(s: &str) -> Result<Self> {
78        // Split into two parts by '.'
79        let parts: Vec<&str> = s.split('.').collect();
80        if parts.len() != 2 {
81            bail!("Invalid transactions collection format");
82        }
83
84        match parts[0].to_uppercase().as_str() {
85            "TX" => Ok(TransactionsCollection::Transactions(
86                parts[1].to_uppercase().as_str().parse()?,
87            )),
88            "TX_RECEIPT" => Ok(TransactionsCollection::TranasactionReceipts(
89                parts[1].to_uppercase().as_str().parse()?,
90            )),
91            _ => bail!("Unknown transactions collection"),
92        }
93    }
94}
95
96impl TryFrom<String> for TransactionsCollection {
97    type Error = anyhow::Error;
98
99    fn try_from(value: String) -> Result<Self> {
100        TransactionsCollection::from_str(&value)
101    }
102}
103
104impl Display for TransactionsCollection {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        match self {
107            TransactionsCollection::Transactions(ref field) => write!(f, "TX.{}", field),
108            TransactionsCollection::TranasactionReceipts(ref field) => {
109                write!(f, "TX_RECEIPT.{}", field)
110            }
111        }
112    }
113}