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