bothan_lib/types/asset_info.rs
1/// Asset information data structure for storing price and timestamp data.
2///
3/// This module provides the [`AssetInfo`] struct which is the core data structure
4/// for representing asset price information throughout the system.
5use bincode::de::Decoder;
6use bincode::enc::Encoder;
7use bincode::error::{DecodeError, EncodeError};
8use bincode::{Decode, Encode};
9use derive_more::Display;
10use rust_decimal::Decimal;
11use serde::{Deserialize, Serialize};
12
13/// Represents price and timestamp information for a specific asset.
14///
15/// `AssetInfo` stores the essential information about an asset's current state,
16/// including its unique identifier, price, and the timestamp of when the information
17/// was last updated. This structure is used throughout the system for storing,
18/// transmitting, and displaying asset information.
19///
20/// The structure implements various traits for serialization, deserialization,
21/// and display, making it compatible with different storage backends and
22/// presentation formats.
23///
24/// # Examples
25///
26/// ```rust
27/// use rust_decimal::Decimal;
28/// use bothan_lib::types::AssetInfo;
29///
30/// // Create a new asset information entry
31/// let asset = AssetInfo::new(
32/// "BTC-USD".to_string(),
33/// Decimal::new(3950000, 2), // $39,500.00
34/// 1634567890000, // Unix timestamp in milliseconds
35/// );
36///
37/// // Access the asset information
38/// assert_eq!(asset.id, "BTC-USD");
39/// assert_eq!(asset.price.to_string(), "39500.00");
40/// ```
41#[derive(Clone, PartialEq, Debug, Display, Serialize, Deserialize)]
42#[display("AssetInfo{{id: {id}, price: {price}, timestamp: {timestamp}}}")]
43pub struct AssetInfo {
44 /// Unique identifier for the asset, typically in the format of a trading pair (e.g., "BTC-USD").
45 pub id: String,
46
47 /// Current price of the asset represented as a high-precision decimal.
48 pub price: Decimal,
49
50 /// Unix timestamp (in milliseconds) when the asset information was last updated.
51 pub timestamp: i64,
52}
53
54impl AssetInfo {
55 /// Creates a new AssetInfo instance with the specified id, price, and timestamp.
56 ///
57 /// This is the recommended way to construct a new AssetInfo instance,
58 /// ensuring all fields are properly initialized.
59 pub fn new(id: String, price: Decimal, timestamp: i64) -> Self {
60 Self {
61 id,
62 price,
63 timestamp,
64 }
65 }
66}
67
68/// Custom binary encoding implementation for efficient serialization.
69///
70/// This implementation ensures that AssetInfo can be efficiently encoded
71/// in a binary format, which is important for storage and network transmission.
72impl Encode for AssetInfo {
73 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
74 Encode::encode(&self.id, encoder)?;
75 Encode::encode(&self.price.serialize(), encoder)?;
76 Encode::encode(&self.timestamp, encoder)
77 }
78}
79
80/// Custom binary decoding implementation for efficient deserialization.
81///
82/// This implementation ensures that AssetInfo can be efficiently decoded
83/// from a binary format, which is important when retrieving from storage
84/// or receiving over the network.
85impl<Context> Decode<Context> for AssetInfo {
86 fn decode<D: Decoder>(decoder: &mut D) -> Result<Self, DecodeError> {
87 let id: String = Decode::decode(decoder)?;
88 let price_serialized: [u8; 16] = Decode::decode(decoder)?;
89 let timestamp: i64 = Decode::decode(decoder)?;
90
91 Ok(AssetInfo {
92 id,
93 price: Decimal::deserialize(price_serialized),
94 timestamp,
95 })
96 }
97}