Skip to main content

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}