price_feeds_metadata.rs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. use {
  2. crate::{
  3. api::types::{
  4. AssetType,
  5. PriceFeedMetadata,
  6. },
  7. state::State,
  8. },
  9. anyhow::Result,
  10. tokio::sync::RwLock,
  11. };
  12. pub const DEFAULT_PRICE_FEEDS_CACHE_UPDATE_INTERVAL: u64 = 600;
  13. #[derive(Default)]
  14. pub struct PriceFeedMetaState {
  15. pub data: RwLock<Vec<PriceFeedMetadata>>,
  16. }
  17. impl PriceFeedMetaState {
  18. pub fn new() -> Self {
  19. Self {
  20. data: RwLock::new(Vec::new()),
  21. }
  22. }
  23. }
  24. /// Allow downcasting State into CacheState for functions that depend on the `Cache` service.
  25. impl<'a> From<&'a State> for &'a PriceFeedMetaState {
  26. fn from(state: &'a State) -> &'a PriceFeedMetaState {
  27. &state.price_feed_meta
  28. }
  29. }
  30. #[async_trait::async_trait]
  31. pub trait PriceFeedMeta {
  32. async fn retrieve_price_feeds_metadata(&self) -> Result<Vec<PriceFeedMetadata>>;
  33. async fn store_price_feeds_metadata(
  34. &self,
  35. price_feeds_metadata: &[PriceFeedMetadata],
  36. ) -> Result<()>;
  37. async fn get_price_feeds_metadata(
  38. &self,
  39. query: Option<String>,
  40. asset_type: Option<AssetType>,
  41. ) -> Result<Vec<PriceFeedMetadata>>;
  42. }
  43. #[async_trait::async_trait]
  44. impl<T> PriceFeedMeta for T
  45. where
  46. for<'a> &'a T: Into<&'a PriceFeedMetaState>,
  47. T: Sync,
  48. {
  49. async fn retrieve_price_feeds_metadata(&self) -> Result<Vec<PriceFeedMetadata>> {
  50. let price_feeds_metadata = self.into().data.read().await;
  51. Ok(price_feeds_metadata.clone())
  52. }
  53. async fn store_price_feeds_metadata(
  54. &self,
  55. price_feeds_metadata: &[PriceFeedMetadata],
  56. ) -> Result<()> {
  57. let mut price_feeds_metadata_write_guard = self.into().data.write().await;
  58. *price_feeds_metadata_write_guard = price_feeds_metadata.to_vec();
  59. Ok(())
  60. }
  61. async fn get_price_feeds_metadata(
  62. &self,
  63. query: Option<String>,
  64. asset_type: Option<AssetType>,
  65. ) -> Result<Vec<PriceFeedMetadata>> {
  66. let mut price_feeds_metadata = self.retrieve_price_feeds_metadata().await?;
  67. // Filter by query if provided
  68. if let Some(query_str) = &query {
  69. price_feeds_metadata.retain(|feed| {
  70. feed.attributes.get("symbol").map_or(false, |symbol| {
  71. symbol.to_lowercase().contains(&query_str.to_lowercase())
  72. })
  73. });
  74. }
  75. // Filter by asset_type if provided
  76. if let Some(asset_type) = &asset_type {
  77. price_feeds_metadata.retain(|feed| {
  78. feed.attributes.get("asset_type").map_or(false, |type_str| {
  79. type_str.to_lowercase() == asset_type.to_string().to_lowercase()
  80. })
  81. });
  82. }
  83. Ok(price_feeds_metadata)
  84. }
  85. }