oauth2_twitter/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_users_me_endpoint::{User, UsersMeEndpoint, UsersMeEndpointError};
7
8//
9#[derive(Debug, Clone)]
10pub struct TwitterUserInfoEndpoint {
11    inner: UsersMeEndpoint,
12}
13impl TwitterUserInfoEndpoint {
14    pub fn new(access_token: impl AsRef<str>) -> Self {
15        Self {
16            inner: UsersMeEndpoint::new(access_token),
17        }
18    }
19}
20
21impl Endpoint for TwitterUserInfoEndpoint {
22    type RenderRequestError = EndpointRenderRequestError;
23
24    type ParseResponseOutput = UserInfo;
25    type ParseResponseError = EndpointParseResponseError;
26
27    fn render_request(&self) -> Result<Request<Body>, Self::RenderRequestError> {
28        self.inner.render_request().map_err(Into::into)
29    }
30
31    fn parse_response(
32        &self,
33        response: Response<Body>,
34    ) -> Result<Self::ParseResponseOutput, Self::ParseResponseError> {
35        UserInfoWrapper::try_from(self.inner.parse_response(response)?)
36            .map(|x| x.0)
37            .map_err(EndpointParseResponseError::ToOutputFailed)
38    }
39}
40
41//
42impl From<UsersMeEndpointError> for EndpointRenderRequestError {
43    fn from(err: UsersMeEndpointError) -> Self {
44        match err {
45            UsersMeEndpointError::UrlParseFailed(err) => Self::Other(Box::new(err)),
46            UsersMeEndpointError::MakeRequestFailed(err) => Self::MakeRequestFailed(err),
47            UsersMeEndpointError::DeResponseBodyFailed(err) => Self::Other(Box::new(err)),
48            UsersMeEndpointError::ResponseBodyIsFail(err) => Self::Other(Box::new(err)),
49        }
50    }
51}
52impl From<UsersMeEndpointError> for EndpointParseResponseError {
53    fn from(err: UsersMeEndpointError) -> Self {
54        match err {
55            UsersMeEndpointError::UrlParseFailed(err) => Self::Other(Box::new(err)),
56            UsersMeEndpointError::MakeRequestFailed(err) => Self::Other(Box::new(err)),
57            UsersMeEndpointError::DeResponseBodyFailed(err) => Self::DeResponseBodyFailed(err),
58            UsersMeEndpointError::ResponseBodyIsFail(err) => Self::Other(Box::new(err)),
59        }
60    }
61}
62
63//
64struct UserInfoWrapper(UserInfo);
65impl TryFrom<User> for UserInfoWrapper {
66    type Error = Box<dyn std::error::Error + Send + Sync>;
67
68    fn try_from(user: User) -> Result<Self, Self::Error> {
69        Ok(Self(UserInfo {
70            uid: user.id.to_owned(),
71            name: Some(user.username.to_owned()),
72            email: None,
73            raw: serde_json::to_value(user)
74                .map(|x| x.as_object().cloned())?
75                .ok_or_else(|| "unreachable".to_owned())?,
76        }))
77    }
78}