Skip to main content

ccxt_core/capability/
flags.rs

1//! Capability bitflags definitions
2
3use bitflags::bitflags;
4use std::fmt;
5
6use super::Capability;
7
8bitflags! {
9    /// Efficient bitflags representation of exchange capabilities
10    ///
11    /// Uses 64 bits to store all 46 capabilities, providing:
12    /// - Compact storage (8 bytes vs 46+ bytes for booleans)
13    /// - Fast set operations (union, intersection, difference)
14    /// - Type-safe capability combinations
15    ///
16    /// # Predefined Sets
17    ///
18    /// - `MARKET_DATA`: All public market data capabilities
19    /// - `TRADING`: All trading capabilities
20    /// - `ACCOUNT`: All account-related capabilities
21    /// - `FUNDING`: All funding capabilities
22    /// - `MARGIN`: All margin/futures capabilities
23    /// - `WEBSOCKET`: All WebSocket capabilities
24    /// - `ALL`: All capabilities enabled
25    /// - `NONE`: No capabilities
26    ///
27    /// # Example
28    ///
29    /// ```rust
30    /// use ccxt_core::capability::Capabilities;
31    ///
32    /// let caps = Capabilities::MARKET_DATA | Capabilities::TRADING;
33    /// assert!(caps.contains(Capabilities::FETCH_TICKER));
34    /// assert!(caps.contains(Capabilities::CREATE_ORDER));
35    /// ```
36    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
37    pub struct Capabilities: u64 {
38        // ==================== Market Data (bits 0-8) ====================
39        const FETCH_MARKETS     = 1 << 0;
40        const FETCH_CURRENCIES  = 1 << 1;
41        const FETCH_TICKER      = 1 << 2;
42        const FETCH_TICKERS     = 1 << 3;
43        const FETCH_ORDER_BOOK  = 1 << 4;
44        const FETCH_TRADES      = 1 << 5;
45        const FETCH_OHLCV       = 1 << 6;
46        const FETCH_STATUS      = 1 << 7;
47        const FETCH_TIME        = 1 << 8;
48
49        // ==================== Trading (bits 9-19) ====================
50        const CREATE_ORDER          = 1 << 9;
51        const CREATE_MARKET_ORDER   = 1 << 10;
52        const CREATE_LIMIT_ORDER    = 1 << 11;
53        const CANCEL_ORDER          = 1 << 12;
54        const CANCEL_ALL_ORDERS     = 1 << 13;
55        const EDIT_ORDER            = 1 << 14;
56        const FETCH_ORDER           = 1 << 15;
57        const FETCH_ORDERS          = 1 << 16;
58        const FETCH_OPEN_ORDERS     = 1 << 17;
59        const FETCH_CLOSED_ORDERS   = 1 << 18;
60        const FETCH_CANCELED_ORDERS = 1 << 19;
61
62        // ==================== Account (bits 20-25) ====================
63        const FETCH_BALANCE      = 1 << 20;
64        const FETCH_MY_TRADES    = 1 << 21;
65        const FETCH_DEPOSITS     = 1 << 22;
66        const FETCH_WITHDRAWALS  = 1 << 23;
67        const FETCH_TRANSACTIONS = 1 << 24;
68        const FETCH_LEDGER       = 1 << 25;
69
70        // ==================== Funding (bits 26-29) ====================
71        const FETCH_DEPOSIT_ADDRESS  = 1 << 26;
72        const CREATE_DEPOSIT_ADDRESS = 1 << 27;
73        const WITHDRAW               = 1 << 28;
74        const TRANSFER               = 1 << 29;
75
76        // ==================== Margin Trading (bits 30-36) ====================
77        const FETCH_BORROW_RATE   = 1 << 30;
78        const FETCH_BORROW_RATES  = 1 << 31;
79        const FETCH_FUNDING_RATE  = 1 << 32;
80        const FETCH_FUNDING_RATES = 1 << 33;
81        const FETCH_POSITIONS     = 1 << 34;
82        const SET_LEVERAGE        = 1 << 35;
83        const SET_MARGIN_MODE     = 1 << 36;
84
85        // ==================== WebSocket (bits 37-45) ====================
86        const WEBSOCKET        = 1 << 37;
87        const WATCH_TICKER     = 1 << 38;
88        const WATCH_TICKERS    = 1 << 39;
89        const WATCH_ORDER_BOOK = 1 << 40;
90        const WATCH_TRADES     = 1 << 41;
91        const WATCH_OHLCV      = 1 << 42;
92        const WATCH_BALANCE    = 1 << 43;
93        const WATCH_ORDERS     = 1 << 44;
94        const WATCH_MY_TRADES  = 1 << 45;
95
96        // ==================== Category Presets ====================
97        /// All public market data capabilities
98        const MARKET_DATA = Self::FETCH_MARKETS.bits()
99            | Self::FETCH_CURRENCIES.bits()
100            | Self::FETCH_TICKER.bits()
101            | Self::FETCH_TICKERS.bits()
102            | Self::FETCH_ORDER_BOOK.bits()
103            | Self::FETCH_TRADES.bits()
104            | Self::FETCH_OHLCV.bits()
105            | Self::FETCH_STATUS.bits()
106            | Self::FETCH_TIME.bits();
107
108        /// All trading capabilities
109        const TRADING = Self::CREATE_ORDER.bits()
110            | Self::CREATE_MARKET_ORDER.bits()
111            | Self::CREATE_LIMIT_ORDER.bits()
112            | Self::CANCEL_ORDER.bits()
113            | Self::CANCEL_ALL_ORDERS.bits()
114            | Self::EDIT_ORDER.bits()
115            | Self::FETCH_ORDER.bits()
116            | Self::FETCH_ORDERS.bits()
117            | Self::FETCH_OPEN_ORDERS.bits()
118            | Self::FETCH_CLOSED_ORDERS.bits()
119            | Self::FETCH_CANCELED_ORDERS.bits();
120
121        /// All account-related capabilities
122        const ACCOUNT = Self::FETCH_BALANCE.bits()
123            | Self::FETCH_MY_TRADES.bits()
124            | Self::FETCH_DEPOSITS.bits()
125            | Self::FETCH_WITHDRAWALS.bits()
126            | Self::FETCH_TRANSACTIONS.bits()
127            | Self::FETCH_LEDGER.bits();
128
129        /// All funding capabilities
130        const FUNDING = Self::FETCH_DEPOSIT_ADDRESS.bits()
131            | Self::CREATE_DEPOSIT_ADDRESS.bits()
132            | Self::WITHDRAW.bits()
133            | Self::TRANSFER.bits();
134
135        /// All margin/futures trading capabilities
136        const MARGIN = Self::FETCH_BORROW_RATE.bits()
137            | Self::FETCH_BORROW_RATES.bits()
138            | Self::FETCH_FUNDING_RATE.bits()
139            | Self::FETCH_FUNDING_RATES.bits()
140            | Self::FETCH_POSITIONS.bits()
141            | Self::SET_LEVERAGE.bits()
142            | Self::SET_MARGIN_MODE.bits();
143
144        /// All WebSocket capabilities
145        const WEBSOCKET_ALL = Self::WEBSOCKET.bits()
146            | Self::WATCH_TICKER.bits()
147            | Self::WATCH_TICKERS.bits()
148            | Self::WATCH_ORDER_BOOK.bits()
149            | Self::WATCH_TRADES.bits()
150            | Self::WATCH_OHLCV.bits()
151            | Self::WATCH_BALANCE.bits()
152            | Self::WATCH_ORDERS.bits()
153            | Self::WATCH_MY_TRADES.bits();
154
155        /// All REST API capabilities (no WebSocket)
156        const REST_ALL = Self::MARKET_DATA.bits()
157            | Self::TRADING.bits()
158            | Self::ACCOUNT.bits()
159            | Self::FUNDING.bits()
160            | Self::MARGIN.bits();
161
162        /// Public-only capabilities (no authentication required)
163        const PUBLIC_ONLY = Self::MARKET_DATA.bits();
164
165        /// All capabilities enabled
166        const ALL = Self::REST_ALL.bits() | Self::WEBSOCKET_ALL.bits();
167    }
168}
169
170impl Capabilities {
171    /// Check if a capability is supported by CCXT-style name
172    ///
173    /// # Example
174    ///
175    /// ```rust
176    /// use ccxt_core::capability::Capabilities;
177    ///
178    /// let caps = Capabilities::MARKET_DATA;
179    /// assert!(caps.has("fetchTicker"));
180    /// assert!(!caps.has("createOrder"));
181    /// ```
182    pub fn has(&self, capability: &str) -> bool {
183        if let Some(cap) = Capability::from_ccxt_name(capability) {
184            self.contains(Self::from(cap))
185        } else {
186            false
187        }
188    }
189
190    /// Get a list of all supported capability names
191    ///
192    /// # Example
193    ///
194    /// ```rust
195    /// use ccxt_core::capability::Capabilities;
196    ///
197    /// let caps = Capabilities::PUBLIC_ONLY;
198    /// let names = caps.supported_capabilities();
199    /// assert!(names.contains(&"fetchTicker"));
200    /// ```
201    pub fn supported_capabilities(&self) -> Vec<&'static str> {
202        Capability::all()
203            .iter()
204            .filter(|cap| self.contains(Self::from(**cap)))
205            .map(Capability::as_ccxt_name)
206            .collect()
207    }
208
209    /// Count the number of enabled capabilities
210    #[inline]
211    pub fn count(&self) -> u32 {
212        self.bits().count_ones()
213    }
214
215    /// Create from an iterator of capabilities
216    // Lint: should_implement_trait
217    // Reason: This method has different semantics than FromIterator - it's a convenience constructor
218    #[allow(clippy::should_implement_trait)]
219    pub fn from_iter<I: IntoIterator<Item = Capability>>(iter: I) -> Self {
220        let mut caps = Self::empty();
221        for cap in iter {
222            caps |= Self::from(cap);
223        }
224        caps
225    }
226}
227
228impl From<Capability> for Capabilities {
229    fn from(cap: Capability) -> Self {
230        Self::from_bits_truncate(cap.bit_position())
231    }
232}
233
234impl fmt::Display for Capabilities {
235    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
236        let caps = self.supported_capabilities();
237        write!(f, "[{}]", caps.join(", "))
238    }
239}