// file: kb_lib/src/db/dtos/pool_listing.rs //! Pool listing DTO. /// Application-facing normalized pool listing DTO. #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] pub struct PoolListingDto { /// Optional numeric primary key. pub id: std::option::Option, /// Related DEX id. pub dex_id: i64, /// Related pool id. pub pool_id: i64, /// Optional related pair id. pub pair_id: std::option::Option, /// Discovery source family. pub source_kind: crate::ObservationSourceKind, /// Optional source endpoint logical name. pub source_endpoint_name: std::option::Option, /// Detection timestamp. pub detected_at: chrono::DateTime, /// Optional initial base reserve estimate. pub initial_base_reserve: std::option::Option, /// Optional initial quote reserve estimate. pub initial_quote_reserve: std::option::Option, /// Optional initial price estimate in quote units. pub initial_price_quote: std::option::Option, /// Update timestamp. pub updated_at: chrono::DateTime, } impl PoolListingDto { /// Creates a new pool listing DTO. pub fn new( dex_id: i64, pool_id: i64, pair_id: std::option::Option, source_kind: crate::ObservationSourceKind, source_endpoint_name: std::option::Option, initial_base_reserve: std::option::Option, initial_quote_reserve: std::option::Option, initial_price_quote: std::option::Option, ) -> Self { let now = chrono::Utc::now(); return Self { id: None, dex_id, pool_id, pair_id, source_kind, source_endpoint_name, detected_at: now, initial_base_reserve, initial_quote_reserve, initial_price_quote, updated_at: now, }; } } impl TryFrom for PoolListingDto { type Error = crate::Error; fn try_from(entity: crate::PoolListingEntity) -> Result { let source_kind_result = crate::ObservationSourceKind::from_i16(entity.source_kind); let source_kind = match source_kind_result { Ok(source_kind) => source_kind, Err(error) => return Err(error), }; let detected_at_result = chrono::DateTime::parse_from_rfc3339(&entity.detected_at); let detected_at = match detected_at_result { Ok(detected_at) => detected_at.with_timezone(&chrono::Utc), Err(error) => { return Err(crate::Error::Db(format!( "cannot parse pool_listing detected_at '{}': {}", entity.detected_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::Error::Db(format!( "cannot parse pool_listing updated_at '{}': {}", entity.updated_at, error ))); }, }; return Ok(Self { id: Some(entity.id), dex_id: entity.dex_id, pool_id: entity.pool_id, pair_id: entity.pair_id, source_kind, source_endpoint_name: entity.source_endpoint_name, detected_at, initial_base_reserve: entity.initial_base_reserve, initial_quote_reserve: entity.initial_quote_reserve, initial_price_quote: entity.initial_price_quote, updated_at, }); } }