decode.rs (4742B)
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, 11 farm::RadrootsFarmRef, 12 kinds::{KIND_FARM, KIND_PLOT}, 13 plot::RadrootsPlot, 14 tags::TAG_D, 15 }; 16 17 use crate::d_tag::validate_d_tag_tag; 18 use crate::error::EventParseError; 19 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent}; 20 21 const TAG_A: &str = "a"; 22 const TAG_P: &str = "p"; 23 const DEFAULT_KIND: u32 = KIND_PLOT; 24 25 fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, EventParseError> { 26 let tag = tags 27 .iter() 28 .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_D)) 29 .ok_or(EventParseError::MissingTag(TAG_D))?; 30 let value = tag 31 .get(1) 32 .map(|s| s.to_string()) 33 .ok_or(EventParseError::InvalidTag(TAG_D))?; 34 if value.trim().is_empty() { 35 return Err(EventParseError::InvalidTag(TAG_D)); 36 } 37 validate_d_tag_tag(&value, TAG_D)?; 38 Ok(value) 39 } 40 41 fn parse_farm_ref(tags: &[Vec<String>]) -> Result<RadrootsFarmRef, EventParseError> { 42 let tag = tags 43 .iter() 44 .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_A)) 45 .ok_or(EventParseError::MissingTag(TAG_A))?; 46 let value = tag 47 .get(1) 48 .map(|s| s.to_string()) 49 .ok_or(EventParseError::InvalidTag(TAG_A))?; 50 let mut parts = value.splitn(3, ':'); 51 let kind = parts 52 .next() 53 .and_then(|v| v.parse::<u32>().ok()) 54 .ok_or(EventParseError::InvalidTag(TAG_A))?; 55 if kind != KIND_FARM { 56 return Err(EventParseError::InvalidTag(TAG_A)); 57 } 58 let pubkey = parts 59 .next() 60 .ok_or(EventParseError::InvalidTag(TAG_A))? 61 .to_string(); 62 let d_tag = parts 63 .next() 64 .ok_or(EventParseError::InvalidTag(TAG_A))? 65 .to_string(); 66 if pubkey.trim().is_empty() || d_tag.trim().is_empty() { 67 return Err(EventParseError::InvalidTag(TAG_A)); 68 } 69 validate_d_tag_tag(&d_tag, TAG_A)?; 70 Ok(RadrootsFarmRef { pubkey, d_tag }) 71 } 72 73 fn parse_farm_pubkey(tags: &[Vec<String>]) -> Result<String, EventParseError> { 74 let tag = tags 75 .iter() 76 .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_P)) 77 .ok_or(EventParseError::MissingTag(TAG_P))?; 78 let value = tag 79 .get(1) 80 .map(|s| s.to_string()) 81 .ok_or(EventParseError::InvalidTag(TAG_P))?; 82 if value.trim().is_empty() { 83 return Err(EventParseError::InvalidTag(TAG_P)); 84 } 85 Ok(value) 86 } 87 88 pub fn plot_from_event( 89 kind: u32, 90 tags: &[Vec<String>], 91 content: &str, 92 ) -> Result<RadrootsPlot, EventParseError> { 93 if kind != DEFAULT_KIND { 94 return Err(EventParseError::InvalidKind { 95 expected: "30350", 96 got: kind, 97 }); 98 } 99 if content.trim().is_empty() { 100 return Err(EventParseError::InvalidJson("content")); 101 } 102 let d_tag = parse_d_tag(tags)?; 103 let farm_ref = parse_farm_ref(tags)?; 104 let farm_pubkey = parse_farm_pubkey(tags)?; 105 let mut plot: RadrootsPlot = 106 serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?; 107 108 if plot.d_tag.trim().is_empty() { 109 plot.d_tag = d_tag; 110 } else if plot.d_tag != d_tag { 111 return Err(EventParseError::InvalidTag(TAG_D)); 112 } 113 114 if plot.farm.pubkey.trim().is_empty() || plot.farm.d_tag.trim().is_empty() { 115 plot.farm = farm_ref; 116 } else if plot.farm.pubkey != farm_ref.pubkey || plot.farm.d_tag != farm_ref.d_tag { 117 return Err(EventParseError::InvalidTag(TAG_A)); 118 } 119 if plot.farm.pubkey != farm_pubkey { 120 return Err(EventParseError::InvalidTag(TAG_P)); 121 } 122 123 Ok(plot) 124 } 125 126 pub fn data_from_event( 127 id: String, 128 author: String, 129 published_at: u32, 130 kind: u32, 131 content: String, 132 tags: Vec<Vec<String>>, 133 ) -> Result<RadrootsParsedData<RadrootsPlot>, EventParseError> { 134 let plot = plot_from_event(kind, &tags, &content)?; 135 Ok(RadrootsParsedData::new( 136 id, 137 author, 138 published_at, 139 kind, 140 plot, 141 )) 142 } 143 144 pub fn parsed_from_event( 145 id: String, 146 author: String, 147 published_at: u32, 148 kind: u32, 149 content: String, 150 tags: Vec<Vec<String>>, 151 sig: String, 152 ) -> Result<RadrootsParsedEvent<RadrootsPlot>, EventParseError> { 153 let data = data_from_event( 154 id.clone(), 155 author.clone(), 156 published_at, 157 kind, 158 content.clone(), 159 tags.clone(), 160 )?; 161 Ok(RadrootsParsedEvent { 162 event: RadrootsNostrEvent { 163 id, 164 author, 165 created_at: published_at, 166 kind, 167 content, 168 tags, 169 sig, 170 }, 171 data, 172 }) 173 }