Переглянути джерело

Add UrlOrEmpty type.

It seems a lot of people are writing empty "" to skip, instead of null :-(.
Cesar Rodas 2 місяців тому
батько
коміт
fe419f39af
1 змінених файлів з 37 додано та 14 видалено
  1. 37 14
      crates/types/src/types/tag.rs

+ 37 - 14
crates/types/src/types/tag.rs

@@ -30,6 +30,24 @@ pub enum Marker {
     Unknown(String),
 }
 
+#[derive(Debug, Clone, PartialEq, Eq)]
+/// Url content or empty string
+pub enum UrlOrEmpty {
+    /// Url
+    Url(Url),
+    /// Empty string
+    Empty,
+}
+
+impl Display for UrlOrEmpty {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match self {
+            Self::Url(url) => write!(f, "{}", url),
+            Self::Empty => write!(f, ""),
+        }
+    }
+}
+
 impl Display for Marker {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(
@@ -78,9 +96,9 @@ pub enum RelayAccessType {
 #[derive(Debug, PartialEq, Eq, Clone)]
 pub enum Tag {
     /// Tag another event
-    Event(Id, Option<Url>, Option<Marker>),
+    Event(Id, Option<UrlOrEmpty>, Option<Marker>),
     /// Tag another public key
-    PubKey(Id, Option<Url>, Option<String>),
+    PubKey(Id, Option<UrlOrEmpty>, Option<String>),
     /// Tag a relay
     Relay(Url, RelayAccessType),
     /// Tag a hashtag
@@ -98,7 +116,7 @@ pub enum Tag {
     /// Image - NIP-23, NIP-52, NIP-58
     Image(Url, Option<String>),
     /// Zap Goal - NIP-75
-    ZapGoal(Id, Option<Url>),
+    ZapGoal(Id, Option<UrlOrEmpty>),
     /// Weird, supported nonetheless
     Empty,
 }
@@ -183,7 +201,7 @@ impl ser::Serialize for Tag {
             Tag::Event(event, relayer_url, marker) => {
                 seq.serialize_element(&event.to_string())?;
                 if let Some(relayer) = &relayer_url {
-                    seq.serialize_element(&relayer)?;
+                    seq.serialize_element(&relayer.to_string())?;
                     if let Some(marker) = &marker {
                         seq.serialize_element(&marker.to_string())?;
                     }
@@ -192,7 +210,7 @@ impl ser::Serialize for Tag {
             Tag::ZapGoal(event, relayer_url) => {
                 seq.serialize_element(&event.to_string())?;
                 if let Some(relayer) = &relayer_url {
-                    seq.serialize_element(&relayer)?;
+                    seq.serialize_element(&relayer.to_string())?;
                 }
             }
             Tag::ExternalContentId(content, url) => {
@@ -207,7 +225,7 @@ impl ser::Serialize for Tag {
             Tag::PubKey(key, relayer_url, pet_name) => {
                 seq.serialize_element(&key.to_string())?;
                 if let Some(relayer) = &relayer_url {
-                    seq.serialize_element(relayer)?;
+                    seq.serialize_element(&relayer.to_string())?;
                     if let Some(pet_name) = &pet_name {
                         seq.serialize_element(pet_name)?;
                     }
@@ -272,7 +290,13 @@ impl<'de> Deserialize<'de> for Tag {
                 .and_then(|id| {
                     let relayer_url = parts
                         .pop_front()
-                        .map(|x| x.parse())
+                        .map(|value| {
+                            if value.is_empty() {
+                                Ok(UrlOrEmpty::Empty)
+                            } else {
+                                value.parse().map(UrlOrEmpty::Url)
+                            }
+                        })
                         .transpose()
                         .map_err(de::Error::custom);
 
@@ -409,13 +433,12 @@ mod test {
                 None,
                 None,
             ),
-            Tag::Unknown(
-                "p".to_owned(),
-                vec![
-                    "8fe53b37518e3dbe9bab26d912292001d8b882de9456b7b08b615f912dc8bf4a".to_owned(),
-                    "".to_owned(),
-                    "mention".to_owned(),
-                ],
+            Tag::PubKey(
+                "8fe53b37518e3dbe9bab26d912292001d8b882de9456b7b08b615f912dc8bf4a"
+                    .parse()
+                    .unwrap(),
+                Some(UrlOrEmpty::Empty),
+                Some("mention".to_owned()),
             ),
             Tag::Event(
                 "eb278e983fcedbb0d143c4250c879d078d037586c5dca8e1cf1a104f9846a460"