// file: kb_lib/src/db/dtos/chain_transaction.rs //! Application-facing normalized chain transaction DTO. /// Application-facing normalized chain transaction DTO. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct KbChainTransactionDto { /// Optional numeric primary key. pub id: std::option::Option, /// Transaction signature. pub signature: std::string::String, /// Optional slot number. pub slot: std::option::Option, /// Optional block time in unix seconds. pub block_time_unix: std::option::Option, /// Optional source endpoint name. pub source_endpoint_name: std::option::Option, /// Optional version text. pub version_text: std::option::Option, /// Optional serialized transaction error JSON. pub err_json: std::option::Option, /// Optional serialized meta JSON. pub meta_json: std::option::Option, /// Serialized full transaction JSON. pub transaction_json: std::string::String, /// Creation timestamp. pub created_at: chrono::DateTime, /// Update timestamp. pub updated_at: chrono::DateTime, } impl KbChainTransactionDto { /// Creates a new chain transaction DTO. #[allow(clippy::too_many_arguments)] pub fn new( signature: std::string::String, slot: std::option::Option, block_time_unix: std::option::Option, source_endpoint_name: std::option::Option, version_text: std::option::Option, err_json: std::option::Option, meta_json: std::option::Option, transaction_json: std::string::String, ) -> Self { let now = chrono::Utc::now(); return Self { id: None, signature, slot, block_time_unix, source_endpoint_name, version_text, err_json, meta_json, transaction_json, created_at: now, updated_at: now, }; } } impl TryFrom for KbChainTransactionDto { type Error = crate::KbError; fn try_from(entity: crate::KbChainTransactionEntity) -> Result { let slot = match entity.slot { Some(slot) => { let slot_result = u64::try_from(slot); match slot_result { Ok(slot) => Some(slot), Err(error) => { return Err(crate::KbError::Db(format!( "cannot convert chain transaction slot '{}' to u64: {}", slot, error ))); }, } }, None => None, }; let created_at_result = chrono::DateTime::parse_from_rfc3339(&entity.created_at); let created_at = match created_at_result { Ok(created_at) => created_at.with_timezone(&chrono::Utc), Err(error) => { return Err(crate::KbError::Db(format!( "cannot parse chain transaction created_at '{}': {}", entity.created_at, error ))); }, }; let updated_at_result = chrono::DateTime::parse_from_rfc3339(&entity.updated_at); let updated_at = match updated_at_result { Ok(updated_at) => updated_at.with_timezone(&chrono::Utc), Err(error) => { return Err(crate::KbError::Db(format!( "cannot parse chain transaction updated_at '{}': {}", entity.updated_at, error ))); }, }; return Ok(Self { id: Some(entity.id), signature: entity.signature, slot, block_time_unix: entity.block_time_unix, source_endpoint_name: entity.source_endpoint_name, version_text: entity.version_text, err_json: entity.err_json, meta_json: entity.meta_json, transaction_json: entity.transaction_json, created_at, updated_at, }); } }