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}