binance/
util.rs

1use anyhow::bail;
2use anyhow::Result;
3use std::collections::BTreeMap;
4use std::time::{SystemTime, UNIX_EPOCH};
5
6pub fn build_query(parameters: BTreeMap<String, String>) -> String {
7  let mut request = String::new();
8  for (key, value) in parameters {
9    let param = format!("{}={}&", key, value);
10    request.push_str(param.as_ref());
11  }
12  request.pop();
13  request
14}
15
16pub fn build_signed_query(
17  parameters: BTreeMap<String, String>,
18  recv_window: u64,
19) -> Result<String> {
20  build_signed_query_custom(parameters, recv_window, SystemTime::now())
21}
22
23pub fn build_signed_query_custom(
24  mut parameters: BTreeMap<String, String>,
25  recv_window: u64,
26  timestamp: SystemTime,
27) -> Result<String> {
28  if recv_window > 0 {
29    parameters.insert("recvWindow".into(), recv_window.to_string());
30  }
31  if let Ok(timestamp) = get_timestamp(timestamp) {
32    parameters.insert("timestamp".into(), timestamp.to_string());
33    return Ok(build_query(parameters));
34  }
35  bail!("Failed to get timestamp")
36}
37
38fn get_timestamp(time: SystemTime) -> Result<u64> {
39  Ok(
40    time
41      .duration_since(UNIX_EPOCH)
42      .expect("Time went backwards")
43      .as_millis() as u64,
44  )
45}
46
47pub fn is_start_time_valid(start_time: &u64) -> bool {
48  let current_time = SystemTime::now()
49    .duration_since(UNIX_EPOCH)
50    .unwrap()
51    .as_secs();
52
53  start_time <= &current_time
54}
55
56pub fn vec_to_string_array(vector: Vec<String>) -> String {
57  format!(
58    "[{}]",
59    vector
60      .iter()
61      .map(|s| format!("\"{}\"", s))
62      .collect::<Vec<_>>()
63      .join(",")
64  )
65}
66
67#[macro_export]
68macro_rules! create_enum_with_fmt {
69  // We handle the first variant separately, then the remaining variants in a list.
70  // This way, we can easily assign the first variant as the enum's default.
71  (
72    $name:ident, {
73      $first_variant:ident => $first_display:expr
74      $(, $variant:ident => $display:expr)* $(,)?
75    }
76  ) => {
77    #[derive(Debug, Clone, Copy)]
78    pub enum $name {
79      $first_variant,
80      $($variant),*
81    }
82
83    /// `Default` returns the **first** variant from the macro's list.
84    impl Default for $name {
85      fn default() -> Self {
86        $name::$first_variant
87      }
88    }
89
90    impl $name {
91      /// Convert a 1-based index to the corresponding variant.
92      /// Returns `None` if index is out of range.
93      pub fn from_int(value: i32) -> Option<Self> {
94        // Check the first variant
95        let mut index = 1;
96        if index == 1 {
97          return Some($name::$first_variant);
98        }
99        // Start indexing for the rest of the variants at 2
100        $(
101        index += 1;
102        if value == index {
103          return Some($name::$variant);
104        }
105        )*
106        None
107      }
108    }
109
110    impl std::fmt::Display for $name {
111      fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
112        match self {
113          $name::$first_variant => write!(f, "{}", $first_display),
114          $(
115          $name::$variant => write!(f, "{}", $display),
116          )*
117        }
118      }
119    }
120  }
121}