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