oauth2_dropbox/extensions/
internal_get_account_endpoint.rs

1use oauth2_client::re_exports::{
2    http::{
3        header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE},
4        Method,
5    },
6    serde_json, thiserror, Body, Deserialize, Endpoint, HttpError, Map, Request, Response,
7    SerdeJsonError, Serialize, Value, MIME_APPLICATION_JSON,
8};
9
10// https://www.dropbox.com/developers/documentation/http/documentation#users-get_account
11pub const URL: &str = "https://api.dropboxapi.com/2/users/get_account";
12
13//
14#[derive(Debug, Clone)]
15pub struct GetAccountEndpoint {
16    access_token: String,
17    account_id: String,
18}
19impl GetAccountEndpoint {
20    pub fn new(access_token: impl AsRef<str>, account_id: impl AsRef<str>) -> Self {
21        Self {
22            access_token: access_token.as_ref().to_owned(),
23            account_id: account_id.as_ref().to_owned(),
24        }
25    }
26}
27
28impl Endpoint for GetAccountEndpoint {
29    type RenderRequestError = GetAccountEndpointError;
30
31    type ParseResponseOutput = Account;
32    type ParseResponseError = GetAccountEndpointError;
33
34    fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
35        let body = GetAccountEndpointRequestBody {
36            account_id: self.account_id.to_owned(),
37        };
38        let body_str =
39            serde_json::to_string(&body).map_err(GetAccountEndpointError::SerResponseBodyFailed)?;
40
41        let request = Request::builder()
42            .uri(URL)
43            .method(Method::POST)
44            .header(AUTHORIZATION, format!("Bearer {}", &self.access_token))
45            .header(CONTENT_TYPE, MIME_APPLICATION_JSON)
46            .header(ACCEPT, MIME_APPLICATION_JSON)
47            .body(body_str.as_bytes().to_vec())
48            .map_err(GetAccountEndpointError::MakeRequestFailed)?;
49
50        Ok(request)
51    }
52
53    fn parse_response(
54        &self,
55        response: Response<Body>,
56    ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
57        let body = serde_json::from_slice::<Account>(response.body())
58            .map_err(GetAccountEndpointError::DeResponseBodyFailed)?;
59
60        Ok(body)
61    }
62}
63
64#[derive(Deserialize, Serialize, Debug, Clone)]
65pub struct GetAccountEndpointRequestBody {
66    pub account_id: String,
67}
68
69#[derive(Deserialize, Serialize, Debug, Clone)]
70pub struct Account {
71    pub account_id: String,
72    pub email: Option<String>,
73    //
74    #[serde(flatten, skip_serializing_if = "Option::is_none")]
75    pub _extra: Option<Map<String, Value>>,
76}
77
78#[derive(thiserror::Error, Debug)]
79pub enum GetAccountEndpointError {
80    #[error("SerResponseBodyFailed {0}")]
81    SerResponseBodyFailed(SerdeJsonError),
82    #[error("MakeRequestFailed {0}")]
83    MakeRequestFailed(HttpError),
84    //
85    #[error("DeResponseBodyFailed {0}")]
86    DeResponseBodyFailed(SerdeJsonError),
87}
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn de_account() {
95        match serde_json::from_str::<Account>(include_str!(
96            "../../tests/response_body_json_files/get_account.json"
97        )) {
98            Ok(account) => {
99                assert_eq!(
100                    account.account_id,
101                    "dbid:AADMB_j_i3y-F9qhVBv68H3eRnzSJ3bZ9Nw"
102                );
103            }
104            Err(err) => panic!("{err}"),
105        }
106    }
107}