decode.rs (2678B)
1 #![cfg(feature = "serde_json")] 2 #![forbid(unsafe_code)] 3 4 #[cfg(not(feature = "std"))] 5 use alloc::{ 6 string::{String, ToString}, 7 vec::Vec, 8 }; 9 10 use radroots_events::{RadrootsNostrEvent, coop::RadrootsCoop, kinds::KIND_COOP, tags::TAG_D}; 11 12 use crate::d_tag::validate_d_tag_tag; 13 use crate::error::EventParseError; 14 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent}; 15 16 const DEFAULT_KIND: u32 = KIND_COOP; 17 18 fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, EventParseError> { 19 let tag = tags 20 .iter() 21 .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_D)) 22 .ok_or(EventParseError::MissingTag(TAG_D))?; 23 let value = tag 24 .get(1) 25 .map(|s| s.to_string()) 26 .ok_or(EventParseError::InvalidTag(TAG_D))?; 27 if value.trim().is_empty() { 28 return Err(EventParseError::InvalidTag(TAG_D)); 29 } 30 validate_d_tag_tag(&value, TAG_D)?; 31 Ok(value) 32 } 33 34 pub fn coop_from_event( 35 kind: u32, 36 tags: &[Vec<String>], 37 content: &str, 38 ) -> Result<RadrootsCoop, EventParseError> { 39 if kind != DEFAULT_KIND { 40 return Err(EventParseError::InvalidKind { 41 expected: "30360", 42 got: kind, 43 }); 44 } 45 if content.trim().is_empty() { 46 return Err(EventParseError::InvalidJson("content")); 47 } 48 let d_tag = parse_d_tag(tags)?; 49 let mut coop: RadrootsCoop = 50 serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?; 51 52 if coop.d_tag.trim().is_empty() { 53 coop.d_tag = d_tag; 54 } else if coop.d_tag != d_tag { 55 return Err(EventParseError::InvalidTag(TAG_D)); 56 } 57 58 Ok(coop) 59 } 60 61 pub fn data_from_event( 62 id: String, 63 author: String, 64 published_at: u32, 65 kind: u32, 66 content: String, 67 tags: Vec<Vec<String>>, 68 ) -> Result<RadrootsParsedData<RadrootsCoop>, EventParseError> { 69 let coop = coop_from_event(kind, &tags, &content)?; 70 Ok(RadrootsParsedData::new( 71 id, 72 author, 73 published_at, 74 kind, 75 coop, 76 )) 77 } 78 79 pub fn parsed_from_event( 80 id: String, 81 author: String, 82 published_at: u32, 83 kind: u32, 84 content: String, 85 tags: Vec<Vec<String>>, 86 sig: String, 87 ) -> Result<RadrootsParsedEvent<RadrootsCoop>, EventParseError> { 88 let data = data_from_event( 89 id.clone(), 90 author.clone(), 91 published_at, 92 kind, 93 content.clone(), 94 tags.clone(), 95 )?; 96 Ok(RadrootsParsedEvent { 97 event: RadrootsNostrEvent { 98 id, 99 author, 100 created_at: published_at, 101 kind, 102 content, 103 tags, 104 sig, 105 }, 106 data, 107 }) 108 }