dcl_rpc/rpc_protocol/mod.rs
1//! Contains the types and functions needed to use the Decentraland RPC implementation.
2pub mod parse;
3// proto file definition doesn't have a package name, so it defaults to "_"
4// TODO: scope the protcolol just to the crate
5include!(concat!(env!("OUT_DIR"), "/_.rs"));
6
7/// This trait should me implemented by the Error type returned in your server's procedures
8///
9/// # Example
10///
11/// ```
12/// use dcl_rpc::rpc_protocol::{RemoteError, RemoteErrorResponse};
13/// pub enum MyEnumOfErrors {
14/// EntityNotFound,
15/// DbError
16/// }
17///
18/// impl RemoteErrorResponse for MyEnumOfErrors {
19/// fn error_code(&self) -> u32 {
20/// match self {
21/// Self::EntityNotFound => 404,
22/// Self::DbError => 500
23/// }
24/// }
25///
26/// fn error_message(&self) -> String {
27/// match self {
28/// Self::EntityNotFound => "The entity wasn't found".to_string(),
29/// Self::DbError => "Internal Server Error".to_string()
30/// }
31/// }
32/// }
33///
34/// let error: RemoteError = MyEnumOfErrors::EntityNotFound.into();
35/// assert_eq!(error.error_code, 404);
36/// assert_eq!(error.error_message, "The entity wasn't found")
37/// ```
38///
39///
40pub trait RemoteErrorResponse {
41 fn error_code(&self) -> u32;
42 fn error_message(&self) -> String;
43}
44
45/// Every type which implements [`RemoteErrorResponse`], it can be turned into a [`RemoteError`]
46impl<T: RemoteErrorResponse> From<T> for RemoteError {
47 fn from(value: T) -> Self {
48 Self {
49 message_identifier: 0, // We cannot know the identifier, it has to be changed after.
50 error_code: value.error_code(),
51 error_message: value.error_message(),
52 }
53 }
54}
55
56/// This functions works for filling a [`RemoteError`]. This is needed because:
57///
58/// When a server procedure returns a custom type as an error, which has to implement [`RemoteErrorResponse`](`super::RemoteErrorResponse`).
59///
60/// That custom type is then turned into a [`RemoteError`] but without a "true" value (`0`) in the `message_identifier` field
61///
62/// Because at the moment of conversion, the `message_number` is not available so the [`RemoteError`] has to be filled then.
63///
64pub(crate) fn fill_remote_error(remote_error: &mut RemoteError, message_number: u32) {
65 remote_error.message_identifier = parse::build_message_identifier(
66 RpcMessageTypes::RemoteErrorResponse as u32,
67 message_number,
68 );
69}
70
71/// Build the [`ServerReady`](`RpcMessageTypes::ServerReady`) message for the client
72pub(crate) fn server_ready_message() -> RpcMessageHeader {
73 RpcMessageHeader {
74 message_identifier: parse::build_message_identifier(RpcMessageTypes::ServerReady as u32, 0),
75 }
76}