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