enostr: use data instead of strings in Pubkey and EventId
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
@@ -1,10 +1,14 @@
|
|||||||
|
use nostr::prelude::secp256k1;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
MessageEmpty,
|
Empty,
|
||||||
MessageDecodeFailed,
|
DecodeFailed,
|
||||||
|
HexDecodeFailed,
|
||||||
InvalidSignature,
|
InvalidSignature,
|
||||||
|
Secp(secp256k1::Error),
|
||||||
Json(serde_json::Error),
|
Json(serde_json::Error),
|
||||||
Generic(String),
|
Generic(String),
|
||||||
}
|
}
|
||||||
@@ -12,17 +16,33 @@ pub enum Error {
|
|||||||
impl std::cmp::PartialEq for Error {
|
impl std::cmp::PartialEq for Error {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
match (self, other) {
|
match (self, other) {
|
||||||
(Error::MessageEmpty, Error::MessageEmpty) => true,
|
(Error::Empty, Error::Empty) => true,
|
||||||
(Error::MessageDecodeFailed, Error::MessageDecodeFailed) => true,
|
(Error::DecodeFailed, Error::DecodeFailed) => true,
|
||||||
|
(Error::HexDecodeFailed, Error::HexDecodeFailed) => true,
|
||||||
(Error::InvalidSignature, Error::InvalidSignature) => true,
|
(Error::InvalidSignature, Error::InvalidSignature) => true,
|
||||||
// This is slightly wrong but whatevs
|
// This is slightly wrong but whatevs
|
||||||
(Error::Json(..), Error::Json(..)) => true,
|
(Error::Json(..), Error::Json(..)) => true,
|
||||||
(Error::Generic(left), Error::Generic(right)) => left == right,
|
(Error::Generic(left), Error::Generic(right)) => left == right,
|
||||||
|
(Error::Secp(left), Error::Secp(right)) => left == right,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Error {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
Self::Empty => write!(f, "message is empty"),
|
||||||
|
Self::DecodeFailed => write!(f, "decoding failed"),
|
||||||
|
Self::InvalidSignature => write!(f, "invalid signature"),
|
||||||
|
Self::HexDecodeFailed => write!(f, "hex decoding failed"),
|
||||||
|
Self::Secp(e) => write!(f, "{e}"),
|
||||||
|
Self::Json(e) => write!(f, "{e}"),
|
||||||
|
Self::Generic(e) => write!(f, "{e}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl std::cmp::Eq for Error {}
|
impl std::cmp::Eq for Error {}
|
||||||
|
|
||||||
impl From<String> for Error {
|
impl From<String> for Error {
|
||||||
@@ -31,6 +51,18 @@ impl From<String> for Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<hex::FromHexError> for Error {
|
||||||
|
fn from(_e: hex::FromHexError) -> Self {
|
||||||
|
Error::HexDecodeFailed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<secp256k1::Error> for Error {
|
||||||
|
fn from(e: secp256k1::Error) -> Self {
|
||||||
|
Error::Secp(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<serde_json::Error> for Error {
|
impl From<serde_json::Error> for Error {
|
||||||
fn from(e: serde_json::Error) -> Self {
|
fn from(e: serde_json::Error) -> Self {
|
||||||
Error::Json(e)
|
Error::Json(e)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::{Error, Pubkey, Result};
|
use crate::{Error, Pubkey};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use log::debug;
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
/// Event is the struct used to represent a Nostr event
|
/// Event is the struct used to represent a Nostr event
|
||||||
@@ -8,7 +9,6 @@ pub struct Event {
|
|||||||
/// 32-bytes sha256 of the the serialized event data
|
/// 32-bytes sha256 of the the serialized event data
|
||||||
pub id: EventId,
|
pub id: EventId,
|
||||||
/// 32-bytes hex-encoded public key of the event creator
|
/// 32-bytes hex-encoded public key of the event creator
|
||||||
#[serde(rename = "pubkey")]
|
|
||||||
pub pubkey: Pubkey,
|
pub pubkey: Pubkey,
|
||||||
/// unix timestamp in seconds
|
/// unix timestamp in seconds
|
||||||
pub created_at: u64,
|
pub created_at: u64,
|
||||||
@@ -39,11 +39,11 @@ impl PartialEq for Event {
|
|||||||
impl Eq for Event {}
|
impl Eq for Event {}
|
||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
pub fn from_json(s: &str) -> Result<Self> {
|
pub fn from_json(s: &str) -> Result<Self, Error> {
|
||||||
serde_json::from_str(s).map_err(Into::into)
|
serde_json::from_str(s).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify(&self) -> Result<Self> {
|
pub fn verify(&self) -> Result<Self, Error> {
|
||||||
return Err(Error::InvalidSignature);
|
return Err(Error::InvalidSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,46 +57,62 @@ impl Event {
|
|||||||
tags: Vec<Vec<String>>,
|
tags: Vec<Vec<String>>,
|
||||||
content: &str,
|
content: &str,
|
||||||
sig: &str,
|
sig: &str,
|
||||||
) -> Result<Self> {
|
) -> Result<Self, Error> {
|
||||||
let event = Event {
|
Ok(Event {
|
||||||
id: id.to_string().into(),
|
id: EventId::from_hex(id)?,
|
||||||
pubkey: pubkey.to_string().into(),
|
pubkey: Pubkey::from_hex(pubkey)?,
|
||||||
created_at,
|
created_at,
|
||||||
kind,
|
kind,
|
||||||
tags,
|
tags,
|
||||||
content: content.to_string(),
|
content: content.to_string(),
|
||||||
sig: sig.to_string(),
|
sig: sig.to_string(),
|
||||||
};
|
})
|
||||||
|
|
||||||
event.verify()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::str::FromStr for Event {
|
impl std::str::FromStr for Event {
|
||||||
type Err = Error;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self> {
|
fn from_str(s: &str) -> Result<Self, Error> {
|
||||||
Event::from_json(s)
|
Event::from_json(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Hash)]
|
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||||
pub struct EventId(String);
|
pub struct EventId([u8; 32]);
|
||||||
|
|
||||||
impl AsRef<str> for EventId {
|
impl EventId {
|
||||||
fn as_ref(&self) -> &str {
|
pub fn hex(&self) -> String {
|
||||||
|
hex::encode(self.bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes(&self) -> &[u8; 32] {
|
||||||
&self.0
|
&self.0
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<String> for EventId {
|
pub fn from_hex(hex_str: &str) -> Result<Self, Error> {
|
||||||
fn from(s: String) -> Self {
|
let evid = EventId(hex::decode(hex_str)?.as_slice().try_into().unwrap());
|
||||||
EventId(s)
|
Ok(evid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<EventId> for String {
|
// Custom serialize function for Pubkey
|
||||||
fn from(evid: EventId) -> Self {
|
impl Serialize for EventId {
|
||||||
evid.0
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&self.hex())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom deserialize function for Pubkey
|
||||||
|
impl<'de> Deserialize<'de> for EventId {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
EventId::from_hex(&s).map_err(serde::de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,61 @@
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone, Hash)]
|
use crate::Error;
|
||||||
pub struct Pubkey(String);
|
use hex;
|
||||||
|
use log::debug;
|
||||||
|
use nostr::key::XOnlyPublicKey;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
impl AsRef<str> for Pubkey {
|
#[derive(Debug, Eq, PartialEq, Clone, Hash)]
|
||||||
fn as_ref(&self) -> &str {
|
pub struct Pubkey(XOnlyPublicKey);
|
||||||
&self.0
|
|
||||||
|
impl Pubkey {
|
||||||
|
pub fn hex(&self) -> String {
|
||||||
|
hex::encode(self.bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bytes(&self) -> [u8; 32] {
|
||||||
|
self.0.serialize()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_hex(hex_str: &str) -> Result<Self, Error> {
|
||||||
|
Ok(Pubkey(XOnlyPublicKey::from_slice(
|
||||||
|
hex::decode(hex_str)?.as_slice(),
|
||||||
|
)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<String> for Pubkey {
|
impl fmt::Display for Pubkey {
|
||||||
fn from(s: String) -> Self {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Pubkey(s)
|
write!(f, "{}", self.hex())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&str> for Pubkey {
|
|
||||||
fn from(s: &str) -> Self {
|
|
||||||
Pubkey(s.to_owned())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Pubkey> for String {
|
impl From<Pubkey> for String {
|
||||||
fn from(pk: Pubkey) -> Self {
|
fn from(pk: Pubkey) -> Self {
|
||||||
pk.0
|
pk.hex()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom serialize function for Pubkey
|
||||||
|
impl Serialize for Pubkey {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(&self.hex())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom deserialize function for Pubkey
|
||||||
|
impl<'de> Deserialize<'de> for Pubkey {
|
||||||
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
debug!("decoding pubkey start");
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
debug!("decoding pubkey {}", &s);
|
||||||
|
Pubkey::from_hex(&s).map_err(serde::de::Error::custom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::Error;
|
use crate::Error;
|
||||||
use crate::Event;
|
use crate::Event;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
use log::debug;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use ewebsock::{WsEvent, WsMessage};
|
use ewebsock::{WsEvent, WsMessage};
|
||||||
@@ -76,19 +77,19 @@ impl RelayMessage {
|
|||||||
// I was lazy and took this from the nostr crate. thx yuki!
|
// I was lazy and took this from the nostr crate. thx yuki!
|
||||||
pub fn from_json(msg: &str) -> Result<Self> {
|
pub fn from_json(msg: &str) -> Result<Self> {
|
||||||
if msg.is_empty() {
|
if msg.is_empty() {
|
||||||
return Err(Error::MessageEmpty);
|
return Err(Error::Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
let v: Vec<Value> = serde_json::from_str(msg).map_err(|_| Error::MessageDecodeFailed)?;
|
let v: Vec<Value> = serde_json::from_str(msg).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
// Notice
|
// Notice
|
||||||
// Relay response format: ["NOTICE", <message>]
|
// Relay response format: ["NOTICE", <message>]
|
||||||
if v[0] == "NOTICE" {
|
if v[0] == "NOTICE" {
|
||||||
if v.len() != 2 {
|
if v.len() != 2 {
|
||||||
return Err(Error::MessageDecodeFailed);
|
return Err(Error::DecodeFailed);
|
||||||
}
|
}
|
||||||
let v_notice: String =
|
let v_notice: String =
|
||||||
serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[1].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
return Ok(Self::notice(v_notice));
|
return Ok(Self::notice(v_notice));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,14 +97,13 @@ impl RelayMessage {
|
|||||||
// Relay response format: ["EVENT", <subscription id>, <event JSON>]
|
// Relay response format: ["EVENT", <subscription id>, <event JSON>]
|
||||||
if v[0] == "EVENT" {
|
if v[0] == "EVENT" {
|
||||||
if v.len() != 3 {
|
if v.len() != 3 {
|
||||||
return Err(Error::MessageDecodeFailed);
|
return Err(Error::DecodeFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let event =
|
let event = Event::from_json(&v[2].to_string()).map_err(|_| Error::DecodeFailed)?;
|
||||||
Event::from_json(&v[2].to_string()).map_err(|_| Error::MessageDecodeFailed)?;
|
|
||||||
|
|
||||||
let subscription_id: String =
|
let subscription_id: String =
|
||||||
serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[1].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
return Ok(Self::event(event, subscription_id));
|
return Ok(Self::event(event, subscription_id));
|
||||||
}
|
}
|
||||||
@@ -112,11 +112,11 @@ impl RelayMessage {
|
|||||||
// Relay response format: ["EOSE", <subscription_id>]
|
// Relay response format: ["EOSE", <subscription_id>]
|
||||||
if v[0] == "EOSE" {
|
if v[0] == "EOSE" {
|
||||||
if v.len() != 2 {
|
if v.len() != 2 {
|
||||||
return Err(Error::MessageDecodeFailed);
|
return Err(Error::DecodeFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let subscription_id: String =
|
let subscription_id: String =
|
||||||
serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[1].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
return Ok(Self::eose(subscription_id));
|
return Ok(Self::eose(subscription_id));
|
||||||
}
|
}
|
||||||
@@ -125,22 +125,22 @@ impl RelayMessage {
|
|||||||
// Relay response format: ["OK", <event_id>, <true|false>, <message>]
|
// Relay response format: ["OK", <event_id>, <true|false>, <message>]
|
||||||
if v[0] == "OK" {
|
if v[0] == "OK" {
|
||||||
if v.len() != 4 {
|
if v.len() != 4 {
|
||||||
return Err(Error::MessageDecodeFailed);
|
return Err(Error::DecodeFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
let event_id: String =
|
let event_id: String =
|
||||||
serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[1].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
let status: bool =
|
let status: bool =
|
||||||
serde_json::from_value(v[2].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[2].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
let message: String =
|
let message: String =
|
||||||
serde_json::from_value(v[3].clone()).map_err(|_| Error::MessageDecodeFailed)?;
|
serde_json::from_value(v[3].clone()).map_err(|_| Error::DecodeFailed)?;
|
||||||
|
|
||||||
return Ok(Self::ok(event_id, status, message));
|
return Ok(Self::ok(event_id, status, message));
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::MessageDecodeFailed)
|
Err(Error::DecodeFailed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,16 +169,19 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(invalid_notice_msg).unwrap_err(),
|
RelayMessage::from_json(invalid_notice_msg).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(invalid_notice_msg_content).unwrap_err(),
|
RelayMessage::from_json(invalid_notice_msg_content).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_handle_valid_event() -> Result<()> {
|
fn test_handle_valid_event() -> Result<()> {
|
||||||
|
use log::debug;
|
||||||
|
|
||||||
|
env_logger::init();
|
||||||
let valid_event_msg = r#"["EVENT", "random_string", {"id":"70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5","pubkey":"379e863e8357163b5bce5d2688dc4f1dcc2d505222fb8d74db600f30535dfdfe","created_at":1612809991,"kind":1,"tags":[],"content":"test","sig":"273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502"}]"#;
|
let valid_event_msg = r#"["EVENT", "random_string", {"id":"70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5","pubkey":"379e863e8357163b5bce5d2688dc4f1dcc2d505222fb8d74db600f30535dfdfe","created_at":1612809991,"kind":1,"tags":[],"content":"test","sig":"273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502"}]"#;
|
||||||
|
|
||||||
let id = "70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5";
|
let id = "70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5";
|
||||||
@@ -190,9 +193,13 @@ mod tests {
|
|||||||
let sig = "273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502";
|
let sig = "273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502";
|
||||||
|
|
||||||
let handled_event = Event::new_dummy(id, pubkey, created_at, kind, tags, content, sig);
|
let handled_event = Event::new_dummy(id, pubkey, created_at, kind, tags, content, sig);
|
||||||
|
debug!("event {:?}", handled_event);
|
||||||
|
|
||||||
|
let msg = RelayMessage::from_json(valid_event_msg);
|
||||||
|
debug!("msg {:?}", msg);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(valid_event_msg)?,
|
msg?,
|
||||||
RelayMessage::event(handled_event?, "random_string".to_string())
|
RelayMessage::event(handled_event?, "random_string".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -208,12 +215,12 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(invalid_event_msg).unwrap_err(),
|
RelayMessage::from_json(invalid_event_msg).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(invalid_event_msg_content).unwrap_err(),
|
RelayMessage::from_json(invalid_event_msg_content).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,13 +241,13 @@ mod tests {
|
|||||||
// Missing subscription ID
|
// Missing subscription ID
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(r#"["EOSE"]"#).unwrap_err(),
|
RelayMessage::from_json(r#"["EOSE"]"#).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
|
|
||||||
// The subscription ID is not string
|
// The subscription ID is not string
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(r#"["EOSE", 404]"#).unwrap_err(),
|
RelayMessage::from_json(r#"["EOSE", 404]"#).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,19 +272,19 @@ mod tests {
|
|||||||
r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30"]"#
|
r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30"]"#
|
||||||
)
|
)
|
||||||
.unwrap_err(),
|
.unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
|
|
||||||
// Invalid status
|
// Invalid status
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, ""]"#).unwrap_err(),
|
RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, ""]"#).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
|
|
||||||
// Invalid message
|
// Invalid message
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, 404]"#).unwrap_err(),
|
RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, 404]"#).unwrap_err(),
|
||||||
Error::MessageDecodeFailed
|
Error::DecodeFailed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,10 @@ impl RelayPool {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to receive a pool event from a list of relays. The function searches each relay in the list in order, attempting to receive a message from each. If a message is received, return it. If no message is received from any relays, None is returned.
|
/// Attempts to receive a pool event from a list of relays. The
|
||||||
|
/// function searches each relay in the list in order, attempting to
|
||||||
|
/// receive a message from each. If a message is received, return it.
|
||||||
|
/// If no message is received from any relays, None is returned.
|
||||||
pub fn try_recv(&mut self) -> Option<PoolEvent<'_>> {
|
pub fn try_recv(&mut self) -> Option<PoolEvent<'_>> {
|
||||||
for relay in &mut self.relays {
|
for relay in &mut self.relays {
|
||||||
let relay = &mut relay.relay;
|
let relay = &mut relay.relay;
|
||||||
@@ -149,6 +152,7 @@ impl RelayPool {
|
|||||||
match msg.try_into() {
|
match msg.try_into() {
|
||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
relay.status = RelayStatus::Connected;
|
relay.status = RelayStatus::Connected;
|
||||||
|
|
||||||
// let's just handle pongs here.
|
// let's just handle pongs here.
|
||||||
// We only need to do this natively.
|
// We only need to do this natively.
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
|||||||
Reference in New Issue
Block a user