Skip to main content

ccxt_core/base_exchange/
requests.rs

1//! Request handling utilities and helper methods
2
3use crate::error::Error;
4use serde_json::Value;
5use std::collections::HashMap;
6
7/// Request utility methods
8pub struct RequestUtils;
9
10impl RequestUtils {
11    /// Builds a URL query string from parameters
12    pub fn build_query_string(params: &HashMap<String, Value>) -> String {
13        if params.is_empty() {
14            return String::new();
15        }
16
17        let pairs: Vec<String> = params
18            .iter()
19            .map(|(k, v)| {
20                let value_str = match v {
21                    Value::String(s) => s.clone(),
22                    Value::Number(n) => n.to_string(),
23                    Value::Bool(b) => b.to_string(),
24                    _ => v.to_string(),
25                };
26                format!("{}={}", k, urlencoding::encode(&value_str))
27            })
28            .collect();
29
30        pairs.join("&")
31    }
32
33    /// Parses a JSON response string
34    pub fn parse_json(response: &str) -> Result<Value, Error> {
35        serde_json::from_str(response).map_err(|e| Error::invalid_request(e.to_string()))
36    }
37
38    /// Handles HTTP error responses by mapping status codes to appropriate errors
39    pub fn handle_http_error(status_code: u16, response: &str) -> Error {
40        match status_code {
41            400 => Error::invalid_request(response.to_string()),
42            401 | 403 => Error::authentication(response.to_string()),
43            404 => Error::invalid_request(format!("Endpoint not found: {response}")),
44            429 => Error::rate_limit(response.to_string(), None),
45            500..=599 => Error::exchange(status_code.to_string(), response),
46            _ => Error::network(format!("HTTP {status_code}: {response}")),
47        }
48    }
49
50    /// Safely extracts a string value from a JSON object
51    pub fn safe_string(dict: &Value, key: &str) -> Option<String> {
52        dict.get(key)
53            .and_then(|v| v.as_str())
54            .map(ToString::to_string)
55    }
56
57    /// Safely extracts an integer value from a JSON object
58    pub fn safe_integer(dict: &Value, key: &str) -> Option<i64> {
59        dict.get(key).and_then(Value::as_i64)
60    }
61
62    /// Safely extracts a float value from a JSON object
63    pub fn safe_float(dict: &Value, key: &str) -> Option<f64> {
64        dict.get(key).and_then(Value::as_f64)
65    }
66
67    /// Safely extracts a boolean value from a JSON object
68    pub fn safe_bool(dict: &Value, key: &str) -> Option<bool> {
69        dict.get(key).and_then(Value::as_bool)
70    }
71}