decode.rs (3295B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{ 3 string::{String, ToString}, 4 vec::Vec, 5 }; 6 7 use radroots_events::{ 8 RadrootsNostrEvent, 9 gift_wrap::{RadrootsGiftWrap, RadrootsGiftWrapRecipient}, 10 kinds::KIND_GIFT_WRAP, 11 }; 12 13 use crate::error::EventParseError; 14 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent}; 15 16 const DEFAULT_KIND: u32 = KIND_GIFT_WRAP; 17 18 fn parse_recipient(tags: &[Vec<String>]) -> Result<RadrootsGiftWrapRecipient, EventParseError> { 19 let tag = tags 20 .iter() 21 .find(|t| t.first().map(|s| s.as_str()) == Some("p")) 22 .ok_or(EventParseError::MissingTag("p"))?; 23 let public_key = tag.get(1).ok_or(EventParseError::InvalidTag("p"))?; 24 if public_key.trim().is_empty() { 25 return Err(EventParseError::InvalidTag("p")); 26 } 27 let relay_url = match tag.get(2) { 28 Some(value) if value.trim().is_empty() => return Err(EventParseError::InvalidTag("p")), 29 Some(value) => Some(value.clone()), 30 None => None, 31 }; 32 Ok(RadrootsGiftWrapRecipient { 33 public_key: public_key.clone(), 34 relay_url, 35 }) 36 } 37 38 fn parse_expiration(tags: &[Vec<String>]) -> Result<Option<u32>, EventParseError> { 39 let value = tags 40 .iter() 41 .find(|t| t.first().map(|s| s.as_str()) == Some("expiration")) 42 .and_then(|t| t.get(1)); 43 let Some(value) = value else { 44 return Ok(None); 45 }; 46 if value.trim().is_empty() { 47 return Err(EventParseError::InvalidTag("expiration")); 48 } 49 let expiration = value 50 .parse::<u32>() 51 .map_err(|e| EventParseError::InvalidNumber("expiration", e))?; 52 Ok(Some(expiration)) 53 } 54 55 pub fn gift_wrap_from_tags( 56 kind: u32, 57 tags: &[Vec<String>], 58 content: &str, 59 ) -> Result<RadrootsGiftWrap, EventParseError> { 60 if kind != DEFAULT_KIND { 61 return Err(EventParseError::InvalidKind { 62 expected: "1059", 63 got: kind, 64 }); 65 } 66 if content.trim().is_empty() { 67 return Err(EventParseError::InvalidTag("content")); 68 } 69 let recipient = parse_recipient(tags)?; 70 let expiration = parse_expiration(tags)?; 71 Ok(RadrootsGiftWrap { 72 recipient, 73 content: content.to_string(), 74 expiration, 75 }) 76 } 77 78 pub fn data_from_event( 79 id: String, 80 author: String, 81 published_at: u32, 82 kind: u32, 83 content: String, 84 tags: Vec<Vec<String>>, 85 ) -> Result<RadrootsParsedData<RadrootsGiftWrap>, EventParseError> { 86 let gift_wrap = gift_wrap_from_tags(kind, &tags, &content)?; 87 Ok(RadrootsParsedData::new( 88 id, 89 author, 90 published_at, 91 kind, 92 gift_wrap, 93 )) 94 } 95 96 pub fn parsed_from_event( 97 id: String, 98 author: String, 99 published_at: u32, 100 kind: u32, 101 content: String, 102 tags: Vec<Vec<String>>, 103 sig: String, 104 ) -> Result<RadrootsParsedEvent<RadrootsGiftWrap>, EventParseError> { 105 let data = data_from_event( 106 id.clone(), 107 author.clone(), 108 published_at, 109 kind, 110 content.clone(), 111 tags.clone(), 112 )?; 113 Ok(RadrootsParsedEvent { 114 event: RadrootsNostrEvent { 115 id, 116 author, 117 created_at: published_at, 118 kind, 119 content, 120 tags, 121 sig, 122 }, 123 data, 124 }) 125 }