proto_types/rpc/mod.rs
1#[cfg(feature = "rpc")]
2include!("./google.rpc.rs");
3
4#[cfg(feature = "rpc")]
5macro_rules! has_impl {
6 ($name:ident) => {
7 paste::paste! {
8 #[doc = "Returns true if the `" $name "` matches the given value."]
9 #[inline]
10 pub fn [< has_ $name >](&self, $name: &str) -> bool {
11 self.$name == $name
12 }
13 }
14 };
15
16 ($name:ident, $name_override:ident) => {
17 paste::paste! {
18 #[doc = "Returns true if the `" $name "` matches the given value."]
19 #[inline]
20 pub fn [< has_ $name >](&self, $name_override: &str) -> bool {
21 self.$name_override == $name_override
22 }
23 }
24 };
25}
26
27#[cfg(all(feature = "serde", feature = "rpc"))]
28mod rpc_serde_impls;
29
30#[cfg(feature = "rpc")]
31mod error_details;
32
33#[cfg(feature = "rpc")]
34mod http;
35
36#[cfg(all(feature = "cel", feature = "rpc"))]
37mod rpc_cel_impls;
38
39/// The `Status` type defines a logical error model that is suitable for
40/// different programming environments, including REST APIs and RPC APIs.
41///
42/// It is
43/// used by [gRPC](<https://github.com/grpc>). Each `Status` message contains
44/// three pieces of data: error code, error message, and error details.
45///
46/// You can find out more about this error model and how to work with it in the
47/// [API Design Guide](<https://cloud.google.com/apis/design/errors>).
48#[derive(Clone, PartialEq, Eq, ::prost::Message)]
49#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
50pub struct Status {
51 /// The status code, which should be an enum value of
52 /// [google.rpc.Code][google.rpc.Code].
53 #[prost(int32, tag = "1")]
54 pub code: i32,
55 /// A developer-facing error message, which should be in English. Any
56 /// user-facing error message should be localized and sent in the
57 /// [google.rpc.Status.details][google.rpc.Status.details] field, or localized
58 /// by the client.
59 #[prost(string, tag = "2")]
60 pub message: ::prost::alloc::string::String,
61 /// A list of messages that carry the error details. There is a common set of
62 /// message types for APIs to use.
63 #[prost(message, repeated, tag = "3")]
64 pub details: ::prost::alloc::vec::Vec<crate::protobuf::Any>,
65}
66
67/// The canonical error codes for gRPC APIs.
68///
69///
70/// Sometimes multiple error codes may apply. Services should return
71/// the most specific error code that applies. For example, prefer
72/// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply.
73/// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`.
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
75#[repr(i32)]
76pub enum Code {
77 /// Not an error; returned on success.
78 ///
79 /// HTTP Mapping: 200 OK
80 Ok = 0,
81 /// The operation was cancelled, typically by the caller.
82 ///
83 /// HTTP Mapping: 499 Client Closed Request
84 Cancelled = 1,
85 /// Unknown error. For example, this error may be returned when
86 /// a `Status` value received from another address space belongs to
87 /// an error space that is not known in this address space. Also
88 /// errors raised by APIs that do not return enough error information
89 /// may be converted to this error.
90 ///
91 /// HTTP Mapping: 500 Internal Server Error
92 Unknown = 2,
93 /// The client specified an invalid argument. Note that this differs
94 /// from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments
95 /// that are problematic regardless of the state of the system
96 /// (e.g., a malformed file name).
97 ///
98 /// HTTP Mapping: 400 Bad Request
99 InvalidArgument = 3,
100 /// The deadline expired before the operation could complete. For operations
101 /// that change the state of the system, this error may be returned
102 /// even if the operation has completed successfully. For example, a
103 /// successful response from a server could have been delayed long
104 /// enough for the deadline to expire.
105 ///
106 /// HTTP Mapping: 504 Gateway Timeout
107 DeadlineExceeded = 4,
108 /// Some requested entity (e.g., file or directory) was not found.
109 ///
110 /// Note to server developers: if a request is denied for an entire class
111 /// of users, such as gradual feature rollout or undocumented allowlist,
112 /// `NOT_FOUND` may be used. If a request is denied for some users within
113 /// a class of users, such as user-based access control, `PERMISSION_DENIED`
114 /// must be used.
115 ///
116 /// HTTP Mapping: 404 Not Found
117 NotFound = 5,
118 /// The entity that a client attempted to create (e.g., file or directory)
119 /// already exists.
120 ///
121 /// HTTP Mapping: 409 Conflict
122 AlreadyExists = 6,
123 /// The caller does not have permission to execute the specified
124 /// operation. `PERMISSION_DENIED` must not be used for rejections
125 /// caused by exhausting some resource (use `RESOURCE_EXHAUSTED`
126 /// instead for those errors). `PERMISSION_DENIED` must not be
127 /// used if the caller can not be identified (use `UNAUTHENTICATED`
128 /// instead for those errors). This error code does not imply the
129 /// request is valid or the requested entity exists or satisfies
130 /// other pre-conditions.
131 ///
132 /// HTTP Mapping: 403 Forbidden
133 PermissionDenied = 7,
134 /// The request does not have valid authentication credentials for the
135 /// operation.
136 ///
137 /// HTTP Mapping: 401 Unauthorized
138 Unauthenticated = 16,
139 /// Some resource has been exhausted, perhaps a per-user quota, or
140 /// perhaps the entire file system is out of space.
141 ///
142 /// HTTP Mapping: 429 Too Many Requests
143 ResourceExhausted = 8,
144 /// The operation was rejected because the system is not in a state
145 /// required for the operation's execution. For example, the directory
146 /// to be deleted is non-empty, an rmdir operation is applied to
147 /// a non-directory, etc.
148 ///
149 /// Service implementors can use the following guidelines to decide
150 /// between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:
151 /// (a) Use `UNAVAILABLE` if the client can retry just the failing call.
152 /// (b) Use `ABORTED` if the client should retry at a higher level. For
153 /// example, when a client-specified test-and-set fails, indicating the
154 /// client should restart a read-modify-write sequence.
155 /// (c) Use `FAILED_PRECONDITION` if the client should not retry until
156 /// the system state has been explicitly fixed. For example, if an "rmdir"
157 /// fails because the directory is non-empty, `FAILED_PRECONDITION`
158 /// should be returned since the client should not retry unless
159 /// the files are deleted from the directory.
160 ///
161 /// HTTP Mapping: 400 Bad Request
162 FailedPrecondition = 9,
163 /// The operation was aborted, typically due to a concurrency issue such as
164 /// a sequencer check failure or transaction abort.
165 ///
166 /// See the guidelines above for deciding between `FAILED_PRECONDITION`,
167 /// `ABORTED`, and `UNAVAILABLE`.
168 ///
169 /// HTTP Mapping: 409 Conflict
170 Aborted = 10,
171 /// The operation was attempted past the valid range. E.g., seeking or
172 /// reading past end-of-file.
173 ///
174 /// Unlike `INVALID_ARGUMENT`, this error indicates a problem that may
175 /// be fixed if the system state changes. For example, a 32-bit file
176 /// system will generate `INVALID_ARGUMENT` if asked to read at an
177 /// offset that is not in the range \[0,2^32-1\], but it will generate
178 /// `OUT_OF_RANGE` if asked to read from an offset past the current
179 /// file size.
180 ///
181 /// There is a fair bit of overlap between `FAILED_PRECONDITION` and
182 /// `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific
183 /// error) when it applies so that callers who are iterating through
184 /// a space can easily look for an `OUT_OF_RANGE` error to detect when
185 /// they are done.
186 ///
187 /// HTTP Mapping: 400 Bad Request
188 OutOfRange = 11,
189 /// The operation is not implemented or is not supported/enabled in this
190 /// service.
191 ///
192 /// HTTP Mapping: 501 Not Implemented
193 Unimplemented = 12,
194 /// Internal errors. This means that some invariants expected by the
195 /// underlying system have been broken. This error code is reserved
196 /// for serious errors.
197 ///
198 /// HTTP Mapping: 500 Internal Server Error
199 Internal = 13,
200 /// The service is currently unavailable. This is most likely a
201 /// transient condition, which can be corrected by retrying with
202 /// a backoff. Note that it is not always safe to retry
203 /// non-idempotent operations.
204 ///
205 /// See the guidelines above for deciding between `FAILED_PRECONDITION`,
206 /// `ABORTED`, and `UNAVAILABLE`.
207 ///
208 /// HTTP Mapping: 503 Service Unavailable
209 Unavailable = 14,
210 /// Unrecoverable data loss or corruption.
211 ///
212 /// HTTP Mapping: 500 Internal Server Error
213 DataLoss = 15,
214}
215impl Code {
216 /// String value of the enum field names used in the ProtoBuf definition.
217 ///
218 /// The values are not transformed in any way and thus are considered stable
219 /// (if the ProtoBuf definition does not change) and safe for programmatic use.
220 #[must_use]
221 #[inline]
222 pub const fn as_str_name(&self) -> &'static str {
223 match self {
224 Self::Ok => "OK",
225 Self::Cancelled => "CANCELLED",
226 Self::Unknown => "UNKNOWN",
227 Self::InvalidArgument => "INVALID_ARGUMENT",
228 Self::DeadlineExceeded => "DEADLINE_EXCEEDED",
229 Self::NotFound => "NOT_FOUND",
230 Self::AlreadyExists => "ALREADY_EXISTS",
231 Self::PermissionDenied => "PERMISSION_DENIED",
232 Self::Unauthenticated => "UNAUTHENTICATED",
233 Self::ResourceExhausted => "RESOURCE_EXHAUSTED",
234 Self::FailedPrecondition => "FAILED_PRECONDITION",
235 Self::Aborted => "ABORTED",
236 Self::OutOfRange => "OUT_OF_RANGE",
237 Self::Unimplemented => "UNIMPLEMENTED",
238 Self::Internal => "INTERNAL",
239 Self::Unavailable => "UNAVAILABLE",
240 Self::DataLoss => "DATA_LOSS",
241 }
242 }
243 /// Creates an enum from field names used in the ProtoBuf definition.
244 #[must_use]
245 #[inline]
246 pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
247 match value {
248 "OK" => Some(Self::Ok),
249 "CANCELLED" => Some(Self::Cancelled),
250 "UNKNOWN" => Some(Self::Unknown),
251 "INVALID_ARGUMENT" => Some(Self::InvalidArgument),
252 "DEADLINE_EXCEEDED" => Some(Self::DeadlineExceeded),
253 "NOT_FOUND" => Some(Self::NotFound),
254 "ALREADY_EXISTS" => Some(Self::AlreadyExists),
255 "PERMISSION_DENIED" => Some(Self::PermissionDenied),
256 "UNAUTHENTICATED" => Some(Self::Unauthenticated),
257 "RESOURCE_EXHAUSTED" => Some(Self::ResourceExhausted),
258 "FAILED_PRECONDITION" => Some(Self::FailedPrecondition),
259 "ABORTED" => Some(Self::Aborted),
260 "OUT_OF_RANGE" => Some(Self::OutOfRange),
261 "UNIMPLEMENTED" => Some(Self::Unimplemented),
262 "INTERNAL" => Some(Self::Internal),
263 "UNAVAILABLE" => Some(Self::Unavailable),
264 "DATA_LOSS" => Some(Self::DataLoss),
265 _ => None,
266 }
267 }
268}
269
270#[cfg(feature = "cel")]
271impl From<Status> for cel::Value {
272 fn from(value: Status) -> Self {
273 let mut cel_map: std::collections::HashMap<cel::objects::Key, Self> =
274 std::collections::HashMap::new();
275
276 cel_map.insert("code".into(), Self::Int(value.code.into()));
277 cel_map.insert("message".into(), Self::String(value.message.into()));
278
279 cel_map.insert("details".into(), value.details.into());
280
281 Self::Map(cel_map.into())
282 }
283}