oauth2_dropbox/extensions/
user_info_endpoint.rs

1use oauth2_client::{
2    extensions::{EndpointParseResponseError, EndpointRenderRequestError, UserInfo},
3    re_exports::{serde_json, Body, Endpoint, Request, Response},
4};
5
6use super::internal_get_account_endpoint::{Account, GetAccountEndpoint, GetAccountEndpointError};
7
8type Uid = String;
9
10//
11#[derive(Debug, Clone)]
12pub struct DropboxUserInfoEndpoint {
13    inner: GetAccountEndpoint,
14    uid: Uid,
15}
16impl DropboxUserInfoEndpoint {
17    pub fn new(
18        access_token: impl AsRef<str>,
19        account_id: impl AsRef<str>,
20        uid: impl AsRef<str>,
21    ) -> Self {
22        Self {
23            inner: GetAccountEndpoint::new(access_token, account_id),
24            uid: uid.as_ref().to_owned(),
25        }
26    }
27}
28
29impl Endpoint for DropboxUserInfoEndpoint {
30    type RenderRequestError = EndpointRenderRequestError;
31
32    type ParseResponseOutput = UserInfo;
33    type ParseResponseError = EndpointParseResponseError;
34
35    fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
36        self.inner.render_request().map_err(Into::into)
37    }
38
39    fn parse_response(
40        &self,
41        response: Response<Body>,
42    ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
43        UserInfoWrapper::try_from((self.uid.to_owned(), self.inner.parse_response(response)?))
44            .map(|x| x.0)
45            .map_err(EndpointParseResponseError::ToOutputFailed)
46    }
47}
48
49//
50impl From<GetAccountEndpointError> for EndpointRenderRequestError {
51    fn from(err: GetAccountEndpointError) -> Self {
52        match err {
53            GetAccountEndpointError::SerResponseBodyFailed(err) => Self::Other(Box::new(err)),
54            GetAccountEndpointError::MakeRequestFailed(err) => Self::MakeRequestFailed(err),
55            GetAccountEndpointError::DeResponseBodyFailed(err) => Self::Other(Box::new(err)),
56        }
57    }
58}
59impl From<GetAccountEndpointError> for EndpointParseResponseError {
60    fn from(err: GetAccountEndpointError) -> Self {
61        match err {
62            GetAccountEndpointError::SerResponseBodyFailed(err) => Self::Other(Box::new(err)),
63            GetAccountEndpointError::MakeRequestFailed(err) => Self::Other(Box::new(err)),
64            GetAccountEndpointError::DeResponseBodyFailed(err) => Self::DeResponseBodyFailed(err),
65        }
66    }
67}
68
69//
70struct UserInfoWrapper(UserInfo);
71impl TryFrom<(Uid, Account)> for UserInfoWrapper {
72    type Error = Box<dyn std::error::Error + Send + Sync>;
73
74    fn try_from((uid, account): (Uid, Account)) -> Result<Self, Self::Error> {
75        Ok(Self(UserInfo {
76            uid,
77            name: None,
78            email: account.email.to_owned(),
79            raw: serde_json::to_value(account)
80                .map(|x| x.as_object().cloned())?
81                .ok_or_else(|| "unreachable".to_owned())?,
82        }))
83    }
84}