1use std::{convert::From, fmt};
2
3#[derive(Debug)]
5#[non_exhaustive]
6pub enum ErrorKind {
7 Http(reqwest::Error),
9 HttpStatus(reqwest::StatusCode),
11 CredentialsBuild(google_cloud_auth::build_errors::Error),
14 Credentials(google_cloud_auth::errors::CredentialsError),
18 TonicMetadata(tonic::metadata::errors::InvalidMetadataValue),
19 GrpcStatus(tonic::transport::Error),
20 UrlError(hyper::http::uri::InvalidUri),
21 InvalidApiUrl(String),
24 HeaderValue(hyper::header::InvalidHeaderValue),
27 IdTokenNeedsImpersonation(IdTokenUnsupportedCredentials),
31 InvalidImpersonationUrl(String),
34 CryptoProviderMissing,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49#[non_exhaustive]
50pub enum IdTokenUnsupportedCredentials {
51 AuthorizedUser,
54 ExternalAccount,
56 ExternalAccountAuthorizedUser,
60 GdchServiceAccount,
62}
63
64impl fmt::Display for IdTokenUnsupportedCredentials {
65 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66 match self {
67 Self::AuthorizedUser => write!(f, "authorized_user credentials"),
68 Self::ExternalAccount => write!(
69 f,
70 "external_account credentials without service_account_impersonation_url"
71 ),
72 Self::ExternalAccountAuthorizedUser => {
73 write!(f, "external_account_authorized_user credentials")
74 }
75 Self::GdchServiceAccount => write!(f, "gdch_service_account credentials"),
76 }
77 }
78}
79
80#[derive(Debug)]
82pub struct Error(Box<ErrorKind>);
83
84impl Error {
85 pub fn kind(&self) -> &ErrorKind {
87 &self.0
88 }
89
90 pub fn into_kind(self) -> ErrorKind {
92 *self.0
93 }
94}
95
96impl fmt::Display for Error {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 use ErrorKind::*;
99 match *self.0 {
100 Http(ref e) => write!(f, "http error: {}", e),
101 HttpStatus(ref s) => write!(f, "http status error: {}", s),
102 CredentialsBuild(ref e) => write!(f, "credentials build error: {}", e),
103 Credentials(ref e) => write!(f, "credentials error: {}", e),
104 GrpcStatus(ref e) => write!(f, "Tonic/gRPC error: {}", e),
105 TonicMetadata(ref e) => write!(f, "Tonic metadata error: {}", e),
106 UrlError(ref e) => write!(f, "Url error: {}", e),
107 InvalidApiUrl(ref e) => write!(f, "Invalid API URL: {}", e),
108 HeaderValue(ref e) => write!(f, "invalid header value: {}", e),
109 IdTokenNeedsImpersonation(ref credentials) => write!(
110 f,
111 "{} cannot mint an ID token; give a service account to impersonate",
112 credentials
113 ),
114 InvalidImpersonationUrl(ref url) => write!(
115 f,
116 "service_account_impersonation_url names no service account: {}",
117 url
118 ),
119 CryptoProviderMissing => write!(
120 f,
121 "the credentials sign with a private key and no rustls CryptoProvider is installed; \
122 install one with CryptoProvider::install_default or enable the auth-default-crypto feature"
123 ),
124 }
125 }
126}
127
128impl std::error::Error for Error {}
129
130impl From<reqwest::Error> for Error {
131 fn from(e: reqwest::Error) -> Self {
132 ErrorKind::Http(e).into()
133 }
134}
135
136impl From<google_cloud_auth::build_errors::Error> for Error {
137 fn from(e: google_cloud_auth::build_errors::Error) -> Self {
138 ErrorKind::CredentialsBuild(e).into()
139 }
140}
141
142impl From<google_cloud_auth::errors::CredentialsError> for Error {
143 fn from(e: google_cloud_auth::errors::CredentialsError) -> Self {
144 ErrorKind::Credentials(e).into()
145 }
146}
147
148impl From<ErrorKind> for Error {
149 fn from(k: ErrorKind) -> Self {
150 Error(Box::new(k))
151 }
152}
153
154impl From<tonic::transport::Error> for Error {
155 fn from(e: tonic::transport::Error) -> Self {
156 ErrorKind::GrpcStatus(e).into()
157 }
158}
159
160impl From<tonic::metadata::errors::InvalidMetadataValue> for Error {
161 fn from(e: tonic::metadata::errors::InvalidMetadataValue) -> Self {
162 ErrorKind::TonicMetadata(e).into()
163 }
164}
165
166impl From<hyper::http::uri::InvalidUri> for Error {
167 fn from(e: hyper::http::uri::InvalidUri) -> Self {
168 ErrorKind::UrlError(e).into()
169 }
170}
171
172impl From<hyper::header::InvalidHeaderValue> for Error {
173 fn from(e: hyper::header::InvalidHeaderValue) -> Self {
174 ErrorKind::HeaderValue(e).into()
175 }
176}
177
178pub type Result<T> = std::result::Result<T, Error>;