deribit_websocket/model/
subscription.rs

1//! Subscription management for WebSocket client
2
3use deribit_base::impl_json_display;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7/// Re-export subscription channel from deribit-base
8use crate::model::SubscriptionChannel;
9
10/// Subscription information
11#[derive(Clone, Serialize, Deserialize)]
12pub struct Subscription {
13    /// Channel name
14    pub channel: String,
15    /// Channel type
16    pub channel_type: SubscriptionChannel,
17    /// Instrument name (if applicable)
18    pub instrument: Option<String>,
19    /// Whether subscription is active
20    pub active: bool,
21}
22
23/// Subscription manager
24#[derive(Debug, Default)]
25pub struct SubscriptionManager {
26    subscriptions: HashMap<String, Subscription>,
27}
28
29impl SubscriptionManager {
30    /// Create a new subscription manager
31    pub fn new() -> Self {
32        Self {
33            subscriptions: HashMap::new(),
34        }
35    }
36
37    /// Add a subscription
38    pub fn add_subscription(
39        &mut self,
40        channel: String,
41        channel_type: SubscriptionChannel,
42        instrument: Option<String>,
43    ) {
44        let subscription = Subscription {
45            channel: channel.clone(),
46            channel_type,
47            instrument,
48            active: true,
49        };
50        self.subscriptions.insert(channel, subscription);
51    }
52
53    /// Add a subscription from channel type
54    pub fn add_subscription_from_channel(&mut self, channel_type: SubscriptionChannel) {
55        let channel = channel_type.to_string();
56        let instrument = match &channel_type {
57            SubscriptionChannel::Ticker(inst)
58            | SubscriptionChannel::OrderBook(inst)
59            | SubscriptionChannel::Trades(inst) => Some(inst.clone()),
60            SubscriptionChannel::ChartTrades { instrument, .. } => Some(instrument.clone()),
61            SubscriptionChannel::UserChanges { instrument, .. } => Some(instrument.clone()),
62            SubscriptionChannel::PriceIndex(currency) => Some(currency.clone()),
63            SubscriptionChannel::EstimatedExpirationPrice(inst)
64            | SubscriptionChannel::MarkPrice(inst)
65            | SubscriptionChannel::Funding(inst)
66            | SubscriptionChannel::Perpetual(inst)
67            | SubscriptionChannel::Quote(inst) => Some(inst.clone()),
68            _ => None,
69        };
70        self.add_subscription(channel, channel_type, instrument);
71    }
72
73    /// Remove a subscription
74    pub fn remove_subscription(&mut self, channel: &str) -> Option<Subscription> {
75        self.subscriptions.remove(channel)
76    }
77
78    /// Get all active subscriptions
79    pub fn active_subscriptions(&self) -> Vec<&Subscription> {
80        self.subscriptions.values().filter(|s| s.active).collect()
81    }
82
83    /// Get subscription by channel
84    pub fn get_subscription(&self, channel: &str) -> Option<&Subscription> {
85        self.subscriptions.get(channel)
86    }
87
88    /// Mark subscription as inactive
89    pub fn deactivate_subscription(&mut self, channel: &str) {
90        if let Some(subscription) = self.subscriptions.get_mut(channel) {
91            subscription.active = false;
92        }
93    }
94
95    /// Reactivate all subscriptions
96    pub fn reactivate_all(&mut self) {
97        for subscription in self.subscriptions.values_mut() {
98            subscription.active = true;
99        }
100    }
101
102    /// Clear all subscriptions
103    pub fn clear(&mut self) {
104        self.subscriptions.clear();
105    }
106
107    /// Get all channel names
108    pub fn get_all_channels(&self) -> Vec<String> {
109        self.subscriptions.keys().cloned().collect()
110    }
111
112    /// Get active channel names
113    pub fn get_active_channels(&self) -> Vec<String> {
114        self.subscriptions
115            .iter()
116            .filter(|(_, sub)| sub.active)
117            .map(|(channel, _)| channel.clone())
118            .collect()
119    }
120}
121
122// Custom Debug implementation for Subscription
123impl std::fmt::Debug for Subscription {
124    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125        f.debug_struct("Subscription")
126            .field("channel", &self.channel)
127            .field("channel_type", &self.channel_type)
128            .field("instrument", &self.instrument)
129            .field("active", &self.active)
130            .finish()
131    }
132}
133
134impl_json_display!(Subscription);