bitwarden_api_base/
util.rs

1//! Utility functions for API operations.
2
3/// URL-encodes a string for use in query parameters.
4pub fn urlencode<T: AsRef<str>>(s: T) -> String {
5    url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
6}
7
8/// Marker struct used for endpoints that require authentication.
9/// It will be included in the request's extensions to signal to the middleware
10/// that authentication is required.
11#[derive(Debug, Clone, Copy)]
12pub enum AuthRequired {
13    /// Basic authentication.
14    Basic,
15    /// Bearer token authentication.
16    Bearer,
17    /// Custom header authentication.
18    Header(&'static str),
19}
20
21/// Content types supported by the API client.
22#[derive(Debug, Clone, PartialEq, Eq)]
23#[allow(dead_code)]
24pub enum ContentType {
25    /// JSON content (application/json).
26    Json,
27    /// Plain text content.
28    Text,
29    /// Unsupported content type.
30    Unsupported(String),
31}
32
33impl From<&str> for ContentType {
34    fn from(content_type: &str) -> Self {
35        if content_type.starts_with("application") && content_type.contains("json") {
36            Self::Json
37        } else if content_type.starts_with("text/plain") {
38            Self::Text
39        } else {
40            Self::Unsupported(content_type.to_string())
41        }
42    }
43}
44
45/// Parses a deep object (nested JSON) into flat query parameters.
46///
47/// This is used for serializing complex query parameters in the OpenAPI
48/// "deepObject" style.
49pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> {
50    if let serde_json::Value::Object(object) = value {
51        let mut params = vec![];
52
53        for (key, value) in object {
54            match value {
55                serde_json::Value::Object(_) => params.append(&mut parse_deep_object(
56                    &format!("{}[{}]", prefix, key),
57                    value,
58                )),
59                serde_json::Value::Array(array) => {
60                    for (i, value) in array.iter().enumerate() {
61                        params.append(&mut parse_deep_object(
62                            &format!("{}[{}][{}]", prefix, key, i),
63                            value,
64                        ));
65                    }
66                }
67                serde_json::Value::String(s) => {
68                    params.push((format!("{}[{}]", prefix, key), s.clone()));
69                }
70                _ => params.push((format!("{}[{}]", prefix, key), value.to_string())),
71            }
72        }
73
74        return params;
75    }
76
77    unimplemented!("Only objects are supported with style=deepObject")
78}