mirror of
https://github.com/floor-licker/polyfill-rs.git
synced 2026-07-27 20:47:46 +00:00
fix: expose book snapshot clocks
This commit is contained in:
@@ -460,6 +460,8 @@ impl OrderBook {
|
||||
bids: self.bids(None), // Get all bids (up to max_depth)
|
||||
asks: self.asks(None), // Get all asks (up to max_depth)
|
||||
sequence: self.last_delta_sequence,
|
||||
last_delta_sequence: self.last_delta_sequence,
|
||||
last_snapshot_timestamp_ms: self.last_snapshot_timestamp_ms,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1526,6 +1528,11 @@ mod tests {
|
||||
assert_eq!(book.last_snapshot_timestamp_ms, 1_000);
|
||||
assert_eq!(book.best_bid().unwrap().price, dec!(0.50));
|
||||
assert_eq!(book.best_ask().unwrap().price, dec!(0.60));
|
||||
|
||||
let snapshot = book.snapshot();
|
||||
assert_eq!(snapshot.sequence, 10_000);
|
||||
assert_eq!(snapshot.last_delta_sequence, 10_000);
|
||||
assert_eq!(snapshot.last_snapshot_timestamp_ms, 1_000);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -341,6 +341,8 @@ impl Decoder<OrderBook> for RawOrderBookResponse {
|
||||
bids,
|
||||
asks,
|
||||
sequence: 0, // TODO: Get from response if available
|
||||
last_delta_sequence: 0,
|
||||
last_snapshot_timestamp_ms: 0,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+57
-2
@@ -358,7 +358,7 @@ impl FastBookLevel {
|
||||
}
|
||||
|
||||
/// Full order book state
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct OrderBook {
|
||||
/// Token ID
|
||||
pub token_id: String,
|
||||
@@ -368,8 +368,47 @@ pub struct OrderBook {
|
||||
pub bids: Vec<BookLevel>,
|
||||
/// Ask orders
|
||||
pub asks: Vec<BookLevel>,
|
||||
/// Sequence number
|
||||
/// Legacy/incremental delta sequence number.
|
||||
///
|
||||
/// This is kept for compatibility. For snapshots produced by this client,
|
||||
/// it is equivalent to [`Self::last_delta_sequence`]. WebSocket snapshot
|
||||
/// timestamps are exposed separately in [`Self::last_snapshot_timestamp_ms`].
|
||||
pub sequence: u64,
|
||||
/// Last accepted legacy/incremental delta sequence number.
|
||||
pub last_delta_sequence: u64,
|
||||
/// Last accepted full-book snapshot timestamp in milliseconds.
|
||||
pub last_snapshot_timestamp_ms: u64,
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for OrderBook {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
#[derive(Deserialize)]
|
||||
struct WireOrderBook {
|
||||
token_id: String,
|
||||
timestamp: DateTime<Utc>,
|
||||
bids: Vec<BookLevel>,
|
||||
asks: Vec<BookLevel>,
|
||||
sequence: u64,
|
||||
#[serde(default)]
|
||||
last_delta_sequence: Option<u64>,
|
||||
#[serde(default)]
|
||||
last_snapshot_timestamp_ms: Option<u64>,
|
||||
}
|
||||
|
||||
let wire = WireOrderBook::deserialize(deserializer)?;
|
||||
Ok(Self {
|
||||
token_id: wire.token_id,
|
||||
timestamp: wire.timestamp,
|
||||
bids: wire.bids,
|
||||
asks: wire.asks,
|
||||
sequence: wire.sequence,
|
||||
last_delta_sequence: wire.last_delta_sequence.unwrap_or(wire.sequence),
|
||||
last_snapshot_timestamp_ms: wire.last_snapshot_timestamp_ms.unwrap_or_default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Order book delta for streaming updates - EXTERNAL API VERSION
|
||||
@@ -1922,4 +1961,20 @@ mod tests {
|
||||
Decimal::from_str("0.00005").unwrap()
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn order_book_snapshot_clocks_default_for_legacy_payloads() {
|
||||
let json = r#"{
|
||||
"token_id":"test_token",
|
||||
"timestamp":"2026-06-23T00:00:00Z",
|
||||
"bids":[],
|
||||
"asks":[],
|
||||
"sequence":42
|
||||
}"#;
|
||||
|
||||
let book: OrderBook = serde_json::from_str(json).unwrap();
|
||||
assert_eq!(book.sequence, 42);
|
||||
assert_eq!(book.last_delta_sequence, 42);
|
||||
assert_eq!(book.last_snapshot_timestamp_ms, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,6 +371,8 @@ mod tests {
|
||||
|
||||
let snapshot = books.get_book("test_asset_id").unwrap();
|
||||
assert_eq!(snapshot.sequence, 0);
|
||||
assert_eq!(snapshot.last_delta_sequence, 0);
|
||||
assert_eq!(snapshot.last_snapshot_timestamp_ms, 1000);
|
||||
assert_eq!(snapshot.timestamp.timestamp_millis(), 1000);
|
||||
assert_eq!(snapshot.bids.len(), 1);
|
||||
assert_eq!(snapshot.asks.len(), 1);
|
||||
@@ -409,6 +411,8 @@ mod tests {
|
||||
|
||||
let snapshot = books.get_book("test_asset_id").unwrap();
|
||||
assert_eq!(snapshot.sequence, 0);
|
||||
assert_eq!(snapshot.last_delta_sequence, 0);
|
||||
assert_eq!(snapshot.last_snapshot_timestamp_ms, 1000);
|
||||
assert_eq!(snapshot.timestamp.timestamp_millis(), 1000);
|
||||
assert_eq!(snapshot.bids.len(), 1);
|
||||
assert_eq!(snapshot.asks.len(), 1);
|
||||
@@ -436,6 +440,8 @@ mod tests {
|
||||
|
||||
let snapshot = books.get_book("test_asset_id").unwrap();
|
||||
assert_eq!(snapshot.sequence, 0);
|
||||
assert_eq!(snapshot.last_delta_sequence, 0);
|
||||
assert_eq!(snapshot.last_snapshot_timestamp_ms, 1000);
|
||||
assert_eq!(snapshot.timestamp.timestamp_millis(), 1000);
|
||||
assert_eq!(snapshot.bids[0].price, dec!(0.51));
|
||||
assert_eq!(snapshot.bids[0].size, dec!(11));
|
||||
|
||||
Reference in New Issue
Block a user