Files
khadhroony-bobobot/kb_lib/src/db/dtos/pool_listing.rs
2026-05-10 00:33:01 +02:00

105 lines
3.8 KiB
Rust

// 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<i64>,
/// Related DEX id.
pub dex_id: i64,
/// Related pool id.
pub pool_id: i64,
/// Optional related pair id.
pub pair_id: std::option::Option<i64>,
/// Discovery source family.
pub source_kind: crate::ObservationSourceKind,
/// Optional source endpoint logical name.
pub source_endpoint_name: std::option::Option<std::string::String>,
/// Detection timestamp.
pub detected_at: chrono::DateTime<chrono::Utc>,
/// Optional initial base reserve estimate.
pub initial_base_reserve: std::option::Option<f64>,
/// Optional initial quote reserve estimate.
pub initial_quote_reserve: std::option::Option<f64>,
/// Optional initial price estimate in quote units.
pub initial_price_quote: std::option::Option<f64>,
/// Update timestamp.
pub updated_at: chrono::DateTime<chrono::Utc>,
}
impl PoolListingDto {
/// Creates a new pool listing DTO.
pub fn new(
dex_id: i64,
pool_id: i64,
pair_id: std::option::Option<i64>,
source_kind: crate::ObservationSourceKind,
source_endpoint_name: std::option::Option<std::string::String>,
initial_base_reserve: std::option::Option<f64>,
initial_quote_reserve: std::option::Option<f64>,
initial_price_quote: std::option::Option<f64>,
) -> 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<crate::PoolListingEntity> for PoolListingDto {
type Error = crate::Error;
fn try_from(entity: crate::PoolListingEntity) -> Result<Self, Self::Error> {
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,
});
}
}