105 lines
3.8 KiB
Rust
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,
|
|
});
|
|
}
|
|
}
|