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