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