Jelajahi Sumber

Merge branch 'improve-tags-parsing' of cesar/nostr-prototype into main

Cesar Rodas 2 bulan lalu
induk
melakukan
475e89ae5c

+ 3 - 1
crates/types/src/lib.rs

@@ -27,7 +27,9 @@ mod regression {
         include_str!("../tests/regression_parsing.json")
             .lines()
             .for_each(|line| {
-                let event: Event = serde_json::from_str(line).unwrap();
+                let event: Event = serde_json::from_str(line).unwrap_or_else(|_| {
+                    panic!("Failed to parse: {}", line);
+                });
                 assert!(event.is_valid().is_ok(), "Failed to parse: {}", line);
             });
     }

+ 31 - 5
crates/types/src/types/tag.rs

@@ -93,6 +93,8 @@ pub enum Tag {
     Title(String),
     /// Any non standard tag
     Unknown(String, Vec<String>),
+    /// Any non standard tag, with non string
+    UnknownJson(String, Vec<serde_json::Value>),
     /// Encrypted - NIP-90
     Encrypted,
     /// Expiration - NIP-40
@@ -129,7 +131,7 @@ impl Tag {
             Tag::ZapGoal(_, _) => "goal",
             Tag::Expiration(_) => "expiration",
             Tag::ExternalContentId(_, _) => "i",
-            Tag::Unknown(u, _) => u,
+            Tag::Unknown(u, _) | Tag::UnknownJson(u, _) => u,
             Tag::Empty => "",
         }
     }
@@ -154,7 +156,7 @@ impl Tag {
             }
             Tag::ZapGoal(event, _) => Some(TagValue::Id(event.clone())),
             Tag::Image(image_url, _) => Some(TagValue::String(image_url.to_string())),
-            Tag::Empty | Tag::Encrypted | Tag::Expiration(_) => None,
+            Tag::UnknownJson(_, _) | Tag::Empty | Tag::Encrypted | Tag::Expiration(_) => None,
         }
     }
 
@@ -180,7 +182,7 @@ impl ser::Serialize for Tag {
         match self {
             Tag::Encrypted => {}
             Tag::Expiration(date) => {
-                seq.serialize_element(&date.timestamp())?;
+                seq.serialize_element(&date.timestamp().to_string())?;
             }
             Tag::Event(event, relayer_url, marker) => {
                 seq.serialize_element(&event.to_string())?;
@@ -226,6 +228,11 @@ impl ser::Serialize for Tag {
                     seq.serialize_element(access)?;
                 }
             }
+            Tag::UnknownJson(_, extra) => {
+                for extra in extra.iter() {
+                    seq.serialize_element(extra)?;
+                }
+            }
             Tag::Unknown(_, extra) => {
                 for extra in extra.iter() {
                     seq.serialize_element(extra)?;
@@ -248,13 +255,32 @@ impl<'de> Deserialize<'de> for Tag {
     where
         D: Deserializer<'de>,
     {
-        let mut parts: VecDeque<String> = Deserialize::deserialize(deserializer)?;
+        let mut parts: VecDeque<serde_json::Value> = Deserialize::deserialize(deserializer)?;
+
+        if !parts
+            .iter()
+            .all(|x| matches!(x, serde_json::Value::String(_)))
+        {
+            // If any of the parts is not a string, do not attempt to parse it
+            // and instead return as a Tag::UnknownJson
+            return Ok(Tag::UnknownJson(
+                parts.pop_front().unwrap_or_default().to_string(),
+                parts.into_iter().collect(),
+            ));
+        }
+
+        let mut parts: VecDeque<_> = parts
+            .into_iter()
+            .map(|x| x.as_str().unwrap_or_default().to_string())
+            .collect();
 
         match parts.len() {
             0 => return Ok(Tag::Empty),
             1 => {
                 let tag_name = parts.pop_front().unwrap_or_default();
-                if tag_name.as_str() == "encrypted" { return Ok(Tag::Encrypted) }
+                if tag_name.as_str() == "encrypted" {
+                    return Ok(Tag::Encrypted);
+                }
                 return Ok(Tag::Unknown(tag_name, vec![]));
             }
             _ => {}

+ 8 - 0
crates/types/tests/regression_parsing.json

@@ -1,2 +1,10 @@
 {"content":"🤙","created_at":1724806560,"id":"f4b1461f37dc847f6dea3dbc1b5470c4dceb23c4046ebbcb80807f62f520f371","kind":7,"pubkey":"b2815682cfc83fcd2c3add05785cf4573dd388457069974cc6d8cca06b3c3b78","sig":"5d6bcf31b72d8a189e0cd2095bf64bf052f0ec88ec0e5c6a669f546b14306204feffa0b453a9591639710fe6341ae53589dcbd0cda2752428bd986ccaf99bf6e","tags":[["e","078fc44df2ba89ae08e2d327d5ab43f31e60765b7517342a74e8a180b943fd71","wss://relay.primal.net","root"],["p","b2815682cfc83fcd2c3add05785cf4573dd388457069974cc6d8cca06b3c3b78"],["e","0612860a3a567a531bde1076a407c50f086f56246f5a0f8e99e061d23cd040b5"],["p","d7df5567015930b17c125b3a7cf29bef23aa5a68d09cd6518d291359606aab7b"]]}
 {"content":"🤣 https://image.nostr.build/f0f21864cb22642fc5d83cd96fc55d5d85a2e469e46e191be50bc71a7a1d9740.jpg ","created_at":1719979685,"id":"85616bf509f2612677a1e59f94cceab07f06fb37240597b260fee42c0295992b","kind":1,"pubkey":"b2815682cfc83fcd2c3add05785cf4573dd388457069974cc6d8cca06b3c3b78","sig":"f3e993413b2b4f4579e535c1559e982bb460446d47c02a7ab2e884fd996da31ea999ad89f2ad707800ab4dbf6966819dfd2c93f2d0f4ce64f79430f00b16c8ed","tags":[["e","4668bb2cc0a1fdb5b328810a22b9bf2e8425ff82a228347ddf97e2d9797cf41b","","root"],["p","32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"],["imeta","url https://image.nostr.build/f0f21864cb22642fc5d83cd96fc55d5d85a2e469e46e191be50bc71a7a1d9740.jpg","blurhash eEFOc0.R0hH[n#%E${%JD+Mzb=xoxZxtIq.7-:xtRjRQxZWUxWn$NH","dim 1280x720"],["r","https://image.nostr.build/f0f21864cb22642fc5d83cd96fc55d5d85a2e469e46e191be50bc71a7a1d9740.jpg"]]}
+{"content":"","created_at":1725560216,"id":"4290c88e7efcfd099f87eaf3e87ab207804e626d0778546bbd13e4a4e8d8607f","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"2eeac78a24ca45d2692ce9def057eb4ea924d940cb79fc4df4ba57cfee42f6f29633fac5f7b02ecf0a55c033a95093e135f5993fd37d636308f6b2f0c9cf72a1","tags":[["d","66d9f5982fca01846df9565c"],["k","sell"],["f","EUR"],["s","pending"],["amt","0"],["fa","300"],["pm","Halcash"],["premium","2"],["source","https://t.me/p2plightning/186648"],["network","mainnet"],["layer","lightning"],["expiration","1725643016"],["y","lnp2pbot"],["z","order"]]}
+{"content":"Missin’ You Like This (feat. Luke Combs) - Post Malone","created_at":1725560203,"id":"879ab52c2138822b2ed8850c5f0e5e25cead6dfb9bb73c97a9a9acba7197f74f","kind":30315,"pubkey":"db91fb387e4b448a379b37ee552b17715d92c6f7d8dc5550e8d1a35d5e1f7911","sig":"6b44a898b5bf1ac88f563d2951f27720ff439736d42c409b8899fbab49ca59a3fd3ad1da14eb8e7747ce49eb25114be61e15e29c61af0d809022d55b23948606","tags":[["d","music"],["expiration","1725560426"],["r","spotify:search:Missin%E2%80%99%20You%20Like%20This%20(feat.%20Luke%20Combs)%20-%20Post%20Malone"]]}
+{"content":"","created_at":1725560185,"id":"99d496bb5eb8ac739f0ccdff1f5107b0f85d203b99a5220ad0de4d741f10b42d","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"545dd10e3809c98bfc8ae00efc4ae60d2f578ff41f47f95d6db362a3f26beb5052d9aa77693a075a31d38992784df6a4637512c60fb2b9b0f5861c0cb579501a","tags":[["d","66d9dcea2fca01846df94107"],["k","buy"],["f","CLP"],["s","waiting-buyer-invoice"],["amt","57424"],["fa","30000"],["pm","Transferencia Bancaria Chile 🇨🇱"],["premium","-2"],["source","https://t.me/p2plightning/186634"],["network","mainnet"],["layer","lightning"],["expiration","1725642985"],["y","lnp2pbot"],["z","order"]]}
+{"content":"","created_at":1725560184,"id":"eb820db7c9b4174e935c810b310aefbc4f3c9c3210241eebe14d95d594099bfa","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"f9d980486c40070d62b2a11be42b6235e7cf4c89400f2a9abdd1b7faf96a17955d58a5460fa17926d70f00e2ef58f3d4c8d1ea8c7e8ecce8cd6888ecb709b65c","tags":[["d","66d9b57b2fca01846df8f272"],["k","buy"],["f","MXN"],["s","waiting-payment"],["amt","0"],["fa","4000","19000"],["pm","Depósito en Efectivo Practicaja BBVA 💵 "],["premium","0"],["source","https://t.me/p2plightning/186646"],["network","mainnet"],["layer","lightning"],["expiration","1725642984"],["y","lnp2pbot"],["z","order"]]}
+{"content":"","created_at":1725560134,"id":"c87fbbc15d2caf495e1766735338ecf6fee3b7bf9f042741ea4437ea6f6a08db","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"b190da06e0bb2c363975df4e349c59e5a82141313bc0f82054d46202d3b64cf82c7863823e957ecb6df9268938458446ce427c438b809863c5102985167a3137","tags":[["d","66d9f5452fca01846df955f8"],["k","sell"],["f","BRL"],["s","pending"],["amt","0"],["fa","100","500"],["pm","PIX 💠"],["premium","5"],["community_id","641f489e70d1a1850ebc41a2"],["source","https://t.me/lnp2pbotbrasil/21198"],["network","mainnet"],["layer","lightning"],["expiration","1725642934"],["y","lnp2pbot"],["z","order"]]}
+{"content":"","created_at":1725560127,"id":"4ececfbb9f0f298ca86d3f4e6529b1a985d6a7eb9e7e451217c32ebf0187dea5","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"99b4dda1d0dc8d277058b56aaa5b6e2de09fee23cb95ab24a2443138b1ea1d29da64eb2b738b8137ddb980afd617eb293a01927ff15edb381bfb6c14181f1871","tags":[["d","66d9dcea2fca01846df94107"],["k","buy"],["f","CLP"],["s","waiting-payment"],["amt","0"],["fa","5000","65000"],["pm","Transferencia Bancaria Chile 🇨🇱"],["premium","-2"],["source","https://t.me/p2plightning/186634"],["network","mainnet"],["layer","lightning"],["expiration","1725642927"],["y","lnp2pbot"],["z","order"]]}
+{"content":"","created_at":1725560111,"id":"01b86d75caeb1b817c58410bbffa17172ded83bedf4977f71caeb75d1fbee37a","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"ae74fd6b641d615afaf92d6025765a1795be176631b081c95aeddede7db8208de0f96fdfa5a1477ebb6ad3cb4f25fb075eb5151fbc0c3c5881aad2c46ea609a1","tags":[["d","66d9e2782fca01846df94710"],["k","sell"],["f","CLP"],["s","canceled"],["amt","0"],["fa","30000"],["pm","Transferencia Banco Santander"],["premium","2"],["source","https://t.me/p2plightning/186639"],["network","mainnet"],["layer","lightning"],["expiration","1725642911"],["y","lnp2pbot"],["z","order"]]}
+{"content":"","created_at":1725560091,"id":"bda969bf820937cf7bccbce8ca6c053c1c1832d44e000efc3093c3c16a1775b1","kind":38383,"pubkey":"fcc2a0bd8f5803f6dd8b201a1ddb67a4b6e268371fe7353d41d2b6684af7a61e","sig":"70138b25806b7509d7cb7d4856c2e630a95ae469e3fb84023935bef9d1aea70305619256a1b30011db6219b2f82e984bc22a5cbda116a7121952b0f02c6bff6a","tags":[["d","66d9f51a2fca01846df95545"],["k","sell"],["f","EUR"],["s","pending"],["amt","0"],["fa","10","100"],["pm","REVOLUT"],["premium","5"],["source","https://t.me/p2plightning/186647"],["network","mainnet"],["layer","lightning"],["expiration","1725642891"],["y","lnp2pbot"],["z","order"]]}