request.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //! Request Message
  2. //!
  3. //! All messages that clients can send to relayers are abstracted in this mod
  4. use crate::{client, common::SerializeDeserialize, types};
  5. use serde::{
  6. de::{self, Deserializer},
  7. ser::{self, SerializeSeq, Serializer},
  8. Deserialize,
  9. };
  10. use std::collections::VecDeque;
  11. custom_derive! {
  12. #[derive(Debug, Clone, EnumFromInner)]
  13. /// Request Messages
  14. ///
  15. /// All requests from clients to relayer are abstracted in this struct
  16. pub enum Request {
  17. /// Close a subscription
  18. Close(client::Close),
  19. /// An Event from a client. This is when a client wants to publish an
  20. /// event. The event must be signed.
  21. Event(client::Event),
  22. /// Creates a subscription. Client tells the relayer which kind of events
  23. /// they'd like to hear about
  24. Request(client::Subscribe),
  25. }
  26. }
  27. impl Request {
  28. /// Returns the current message as a Request, if possible
  29. pub fn as_request(&self) -> Option<&client::Subscribe> {
  30. match self {
  31. Self::Request(x) => Some(x),
  32. _ => None,
  33. }
  34. }
  35. /// Returns the current message as a close if possible
  36. pub fn as_close(&self) -> Option<&client::Close> {
  37. match self {
  38. Self::Close(t) => Some(t),
  39. _ => None,
  40. }
  41. }
  42. /// Returns the current message as an event from the client, if possible
  43. pub fn as_event(&self) -> Option<&types::Event> {
  44. match self {
  45. Self::Event(event) => Some(&**event),
  46. _ => None,
  47. }
  48. }
  49. }
  50. impl From<types::Event> for Request {
  51. fn from(event: types::Event) -> Self {
  52. Self::Event(event.into())
  53. }
  54. }
  55. impl ser::Serialize for Request {
  56. fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
  57. where
  58. S: Serializer,
  59. {
  60. let values = match self {
  61. Self::Close(t) => t.serialize(),
  62. Self::Event(t) => t.serialize(),
  63. Self::Request(t) => t.serialize(),
  64. }
  65. .map_err(ser::Error::custom)?;
  66. let mut seq = serializer.serialize_seq(Some(values.len()))?;
  67. for value in values.iter() {
  68. seq.serialize_element(value)?;
  69. }
  70. seq.end()
  71. }
  72. }
  73. impl<'de> de::Deserialize<'de> for Request {
  74. fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  75. where
  76. D: Deserializer<'de>,
  77. {
  78. let mut array: VecDeque<serde_json::Value> = Deserialize::deserialize(deserializer)?;
  79. if array.is_empty() {
  80. return Err(de::Error::custom(
  81. "Invalid array length, expecting at least one",
  82. ));
  83. }
  84. let tag = array
  85. .remove(0)
  86. .ok_or_else(|| de::Error::custom("Invalid array length, expecting at least one"))?;
  87. let tag = tag
  88. .as_str()
  89. .ok_or_else(|| de::Error::custom("Invalid type for element 0 of the array"))?;
  90. match tag {
  91. "EVENT" => Ok(client::Event::deserialize(array)
  92. .map_err(de::Error::custom)?
  93. .into()),
  94. "CLOSE" => Ok(client::Close::deserialize(array)
  95. .map_err(de::Error::custom)?
  96. .into()),
  97. "REQ" => Ok(client::Subscribe::deserialize(array)
  98. .map_err(de::Error::custom)?
  99. .into()),
  100. tag => Err(de::Error::custom(format!("{} is not a support tag", tag))),
  101. }
  102. }
  103. }
  104. #[cfg(test)]
  105. mod test {
  106. use super::*;
  107. #[test]
  108. fn unsupported() {
  109. let json = "[\"CLOSEX\", \"foo\"]";
  110. let message: Result<Request, _> = serde_json::from_str(json);
  111. assert!(message.is_err());
  112. }
  113. #[test]
  114. fn close() {
  115. let json = "[\"CLOSE\", \"foo\"]";
  116. let message: Request = serde_json::from_str(json).expect("valid message");
  117. let subscription_id = message.as_close().expect("valid subscription_id");
  118. assert_eq!("foo".to_owned(), subscription_id.to_string());
  119. }
  120. }