oauth2_twitter/extensions/
user_info_endpoint.rs1use 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#[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
41impl 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
63struct 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}