ws.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //! Websocket types
  2. use serde::de::DeserializeOwned;
  3. use serde::{Deserialize, Serialize};
  4. use super::{NotificationPayload, Params};
  5. /// JSON RPC version
  6. pub const JSON_RPC_VERSION: &str = "2.0";
  7. /// The response to a subscription request
  8. #[derive(Debug, Clone, Serialize, Deserialize)]
  9. #[serde(bound = "I: Serialize + DeserializeOwned")]
  10. pub struct WsSubscribeResponse<I> {
  11. /// Status
  12. pub status: String,
  13. /// Subscription ID
  14. #[serde(rename = "subId")]
  15. pub sub_id: I,
  16. }
  17. /// The response to an unsubscription request
  18. #[derive(Debug, Clone, Serialize, Deserialize)]
  19. #[serde(bound = "I: Serialize + DeserializeOwned")]
  20. pub struct WsUnsubscribeResponse<I> {
  21. /// Status
  22. pub status: String,
  23. /// Subscription ID
  24. #[serde(rename = "subId")]
  25. pub sub_id: I,
  26. }
  27. /// The notification
  28. ///
  29. /// This is the notification that is sent to the client when an event matches a
  30. /// subscription
  31. #[derive(Debug, Clone, Serialize, Deserialize)]
  32. #[serde(bound = "T: Serialize + DeserializeOwned, I: Serialize + DeserializeOwned")]
  33. pub struct NotificationInner<T, I>
  34. where
  35. T: Clone,
  36. {
  37. /// The subscription ID
  38. #[serde(rename = "subId")]
  39. pub sub_id: I,
  40. /// The notification payload
  41. pub payload: NotificationPayload<T>,
  42. }
  43. /// Responses from the web socket server
  44. #[derive(Debug, Clone, Serialize, Deserialize)]
  45. #[serde(bound = "I: Serialize + DeserializeOwned")]
  46. #[serde(untagged)]
  47. pub enum WsResponseResult<I> {
  48. /// A response to a subscription request
  49. Subscribe(WsSubscribeResponse<I>),
  50. /// Unsubscribe
  51. Unsubscribe(WsUnsubscribeResponse<I>),
  52. }
  53. impl<I> From<WsSubscribeResponse<I>> for WsResponseResult<I> {
  54. fn from(response: WsSubscribeResponse<I>) -> Self {
  55. WsResponseResult::Subscribe(response)
  56. }
  57. }
  58. impl<I> From<WsUnsubscribeResponse<I>> for WsResponseResult<I> {
  59. fn from(response: WsUnsubscribeResponse<I>) -> Self {
  60. WsResponseResult::Unsubscribe(response)
  61. }
  62. }
  63. /// The request to unsubscribe
  64. #[derive(Debug, Clone, Serialize, Deserialize)]
  65. #[serde(bound = "I: Serialize + DeserializeOwned")]
  66. pub struct WsUnsubscribeRequest<I> {
  67. /// Subscription ID
  68. #[serde(rename = "subId")]
  69. pub sub_id: I,
  70. }
  71. /// The inner method of the websocket request
  72. #[derive(Debug, Clone, Serialize, Deserialize)]
  73. #[serde(rename_all = "snake_case", tag = "method", content = "params")]
  74. #[serde(bound = "I: Serialize + DeserializeOwned")]
  75. pub enum WsMethodRequest<I> {
  76. /// Subscribe method
  77. Subscribe(Params<I>),
  78. /// Unsubscribe method
  79. Unsubscribe(WsUnsubscribeRequest<I>),
  80. }
  81. /// Websocket request
  82. #[derive(Debug, Clone, Serialize, Deserialize)]
  83. #[serde(bound = "I: Serialize + DeserializeOwned")]
  84. pub struct WsRequest<I> {
  85. /// JSON RPC version
  86. pub jsonrpc: String,
  87. /// The method body
  88. #[serde(flatten)]
  89. pub method: WsMethodRequest<I>,
  90. /// The request ID
  91. pub id: usize,
  92. }
  93. impl<I> From<(WsMethodRequest<I>, usize)> for WsRequest<I> {
  94. fn from((method, id): (WsMethodRequest<I>, usize)) -> Self {
  95. WsRequest {
  96. jsonrpc: JSON_RPC_VERSION.to_owned(),
  97. method,
  98. id,
  99. }
  100. }
  101. }
  102. /// Notification from the server
  103. #[derive(Debug, Clone, Serialize, Deserialize)]
  104. pub struct WsNotification<T> {
  105. /// JSON RPC version
  106. pub jsonrpc: String,
  107. /// The method
  108. pub method: String,
  109. /// The parameters
  110. pub params: T,
  111. }
  112. /// Websocket error
  113. #[derive(Debug, Clone, Deserialize, Serialize)]
  114. pub struct WsErrorBody {
  115. /// Error code
  116. pub code: i32,
  117. /// Error message
  118. pub message: String,
  119. }
  120. /// Websocket response
  121. #[derive(Debug, Clone, Serialize, Deserialize)]
  122. #[serde(bound = "I: Serialize + DeserializeOwned")]
  123. pub struct WsResponse<I> {
  124. /// JSON RPC version
  125. pub jsonrpc: String,
  126. /// The result
  127. pub result: WsResponseResult<I>,
  128. /// The request ID
  129. pub id: usize,
  130. }
  131. /// WebSocket error response
  132. #[derive(Debug, Clone, Serialize, Deserialize)]
  133. pub struct WsErrorResponse {
  134. /// JSON RPC version
  135. pub jsonrpc: String,
  136. /// The result
  137. pub error: WsErrorBody,
  138. /// The request ID
  139. pub id: usize,
  140. }
  141. /// Message from the server to the client
  142. #[derive(Debug, Clone, Serialize, Deserialize)]
  143. #[serde(bound = "I: Serialize + DeserializeOwned")]
  144. #[serde(untagged)]
  145. pub enum WsMessageOrResponse<I> {
  146. /// A response to a request
  147. Response(WsResponse<I>),
  148. /// An error response
  149. ErrorResponse(WsErrorResponse),
  150. /// A notification
  151. Notification(WsNotification<NotificationInner<String, I>>),
  152. }
  153. impl<I> From<(usize, Result<WsResponseResult<I>, WsErrorBody>)> for WsMessageOrResponse<I> {
  154. fn from((id, result): (usize, Result<WsResponseResult<I>, WsErrorBody>)) -> Self {
  155. match result {
  156. Ok(result) => WsMessageOrResponse::Response(WsResponse {
  157. jsonrpc: JSON_RPC_VERSION.to_owned(),
  158. result,
  159. id,
  160. }),
  161. Err(err) => WsMessageOrResponse::ErrorResponse(WsErrorResponse {
  162. jsonrpc: JSON_RPC_VERSION.to_owned(),
  163. error: err,
  164. id,
  165. }),
  166. }
  167. }
  168. }