bitwarden_api_identity/apis/
mod.rs

1use std::{error, fmt};
2
3#[derive(Debug, Clone)]
4pub struct ResponseContent<T> {
5    pub status: reqwest::StatusCode,
6    pub content: String,
7    pub entity: Option<T>,
8}
9
10#[derive(Debug)]
11pub enum Error<T> {
12    Reqwest(reqwest::Error),
13    ReqwestMiddleware(reqwest_middleware::Error),
14    Serde(serde_json::Error),
15    Io(std::io::Error),
16    ResponseError(ResponseContent<T>),
17}
18
19impl<T> fmt::Display for Error<T> {
20    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21        let (module, e) = match self {
22            Error::Reqwest(e) => ("reqwest", e.to_string()),
23            Error::ReqwestMiddleware(e) => ("reqwest-middleware", e.to_string()),
24            Error::Serde(e) => ("serde", e.to_string()),
25            Error::Io(e) => ("IO", e.to_string()),
26            Error::ResponseError(e) => ("response", format!("status code {}", e.status)),
27        };
28        write!(f, "error in {}: {}", module, e)
29    }
30}
31
32impl<T: fmt::Debug> error::Error for Error<T> {
33    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
34        Some(match self {
35            Error::Reqwest(e) => e,
36            Error::ReqwestMiddleware(e) => e,
37            Error::Serde(e) => e,
38            Error::Io(e) => e,
39            Error::ResponseError(_) => return None,
40        })
41    }
42}
43
44impl<T> From<reqwest::Error> for Error<T> {
45    fn from(e: reqwest::Error) -> Self {
46        Error::Reqwest(e)
47    }
48}
49
50impl<T> From<reqwest_middleware::Error> for Error<T> {
51    fn from(e: reqwest_middleware::Error) -> Self {
52        Error::ReqwestMiddleware(e)
53    }
54}
55
56impl<T> From<serde_json::Error> for Error<T> {
57    fn from(e: serde_json::Error) -> Self {
58        Error::Serde(e)
59    }
60}
61
62impl<T> From<std::io::Error> for Error<T> {
63    fn from(e: std::io::Error) -> Self {
64        Error::Io(e)
65    }
66}
67
68pub fn urlencode<T: AsRef<str>>(s: T) -> String {
69    ::url::form_urlencoded::byte_serialize(s.as_ref().as_bytes()).collect()
70}
71
72pub fn parse_deep_object(prefix: &str, value: &serde_json::Value) -> Vec<(String, String)> {
73    if let serde_json::Value::Object(object) = value {
74        let mut params = vec![];
75
76        for (key, value) in object {
77            match value {
78                serde_json::Value::Object(_) => params.append(&mut parse_deep_object(
79                    &format!("{}[{}]", prefix, key),
80                    value,
81                )),
82                serde_json::Value::Array(array) => {
83                    for (i, value) in array.iter().enumerate() {
84                        params.append(&mut parse_deep_object(
85                            &format!("{}[{}][{}]", prefix, key, i),
86                            value,
87                        ));
88                    }
89                }
90                serde_json::Value::String(s) => {
91                    params.push((format!("{}[{}]", prefix, key), s.clone()))
92                }
93                _ => params.push((format!("{}[{}]", prefix, key), value.to_string())),
94            }
95        }
96
97        return params;
98    }
99
100    unimplemented!("Only objects are supported with style=deepObject")
101}
102
103/// Internal use only
104/// A content type supported by this client.
105#[allow(dead_code)]
106enum ContentType {
107    Json,
108    Text,
109    Unsupported(String),
110}
111
112impl From<&str> for ContentType {
113    fn from(content_type: &str) -> Self {
114        if content_type.starts_with("application") && content_type.contains("json") {
115            return Self::Json;
116        } else if content_type.starts_with("text/plain") {
117            return Self::Text;
118        } else {
119            return Self::Unsupported(content_type.to_string());
120        }
121    }
122}
123
124pub mod accounts_api;
125pub mod info_api;
126pub mod sso_api;
127
128pub mod configuration;
129
130use std::sync::Arc;
131
132#[allow(clippy::large_enum_variant, private_interfaces)]
133pub enum ApiClient {
134    Real(ApiClientReal),
135    #[cfg(feature = "mockall")]
136    Mock(ApiClientMock),
137}
138
139struct ApiClientReal {
140    accounts_api: accounts_api::AccountsApiClient,
141    info_api: info_api::InfoApiClient,
142    sso_api: sso_api::SsoApiClient,
143}
144
145#[cfg(feature = "mockall")]
146pub struct ApiClientMock {
147    pub accounts_api: accounts_api::MockAccountsApi,
148    pub info_api: info_api::MockInfoApi,
149    pub sso_api: sso_api::MockSsoApi,
150}
151
152impl ApiClient {
153    pub fn new(configuration: &Arc<configuration::Configuration>) -> Self {
154        Self::Real(ApiClientReal {
155            accounts_api: accounts_api::AccountsApiClient::new(configuration.clone()),
156            info_api: info_api::InfoApiClient::new(configuration.clone()),
157            sso_api: sso_api::SsoApiClient::new(configuration.clone()),
158        })
159    }
160
161    #[cfg(feature = "mockall")]
162    pub fn new_mocked(func: impl FnOnce(&mut ApiClientMock)) -> Self {
163        let mut mock = ApiClientMock {
164            accounts_api: accounts_api::MockAccountsApi::new(),
165            info_api: info_api::MockInfoApi::new(),
166            sso_api: sso_api::MockSsoApi::new(),
167        };
168        func(&mut mock);
169        Self::Mock(mock)
170    }
171}
172
173impl ApiClient {
174    pub fn accounts_api(&self) -> &dyn accounts_api::AccountsApi {
175        match self {
176            ApiClient::Real(real) => &real.accounts_api,
177            #[cfg(feature = "mockall")]
178            ApiClient::Mock(mock) => &mock.accounts_api,
179        }
180    }
181    pub fn info_api(&self) -> &dyn info_api::InfoApi {
182        match self {
183            ApiClient::Real(real) => &real.info_api,
184            #[cfg(feature = "mockall")]
185            ApiClient::Mock(mock) => &mock.info_api,
186        }
187    }
188    pub fn sso_api(&self) -> &dyn sso_api::SsoApi {
189        match self {
190            ApiClient::Real(real) => &real.sso_api,
191            #[cfg(feature = "mockall")]
192            ApiClient::Mock(mock) => &mock.sso_api,
193        }
194    }
195}