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