decode.rs (3513B)
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::{RadrootsNostrEvent, farm::RadrootsFarm, kinds::KIND_FARM, tags::TAG_D}; 10 11 use crate::d_tag::validate_d_tag_tag; 12 use crate::error::EventParseError; 13 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent}; 14 15 const DEFAULT_KIND: u32 = KIND_FARM; 16 17 fn parse_d_tag(tags: &[Vec<String>]) -> Result<String, EventParseError> { 18 let tag = tags 19 .iter() 20 .find(|t| t.first().map(|s| s.as_str()) == Some(TAG_D)) 21 .ok_or(EventParseError::MissingTag(TAG_D))?; 22 let value = tag 23 .get(1) 24 .map(|s| s.to_string()) 25 .ok_or(EventParseError::InvalidTag(TAG_D))?; 26 if value.trim().is_empty() { 27 return Err(EventParseError::InvalidTag(TAG_D)); 28 } 29 validate_d_tag_tag(&value, TAG_D)?; 30 Ok(value) 31 } 32 33 pub fn farm_from_event( 34 kind: u32, 35 tags: &[Vec<String>], 36 content: &str, 37 ) -> Result<RadrootsFarm, EventParseError> { 38 if kind != DEFAULT_KIND { 39 return Err(EventParseError::InvalidKind { 40 expected: "30340", 41 got: kind, 42 }); 43 } 44 if content.trim().is_empty() { 45 return Err(EventParseError::InvalidJson("content")); 46 } 47 let d_tag = parse_d_tag(tags)?; 48 reject_private_farm_ops_content(content)?; 49 let mut farm: RadrootsFarm = 50 serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?; 51 52 if farm.d_tag.trim().is_empty() { 53 farm.d_tag = d_tag; 54 } else if farm.d_tag != d_tag { 55 return Err(EventParseError::InvalidTag(TAG_D)); 56 } 57 58 Ok(farm) 59 } 60 61 fn reject_private_farm_ops_content(content: &str) -> Result<(), EventParseError> { 62 let value: serde_json::Value = 63 serde_json::from_str(content).map_err(|_| EventParseError::InvalidJson("content"))?; 64 let Some(object) = value.as_object() else { 65 return Err(EventParseError::InvalidJson("content")); 66 }; 67 for key in [ 68 "workspace", 69 "farm_group_id", 70 "document_id", 71 "document_kind", 72 "crdt_backend", 73 "encoded_change", 74 "semantic_kind", 75 "owner_document_kind", 76 "owner_document_id", 77 "relays", 78 "media_servers", 79 "supported_kinds", 80 "protocol_version", 81 ] { 82 if object.contains_key(key) { 83 return Err(EventParseError::InvalidJson("content")); 84 } 85 } 86 Ok(()) 87 } 88 89 pub fn data_from_event( 90 id: String, 91 author: String, 92 published_at: u32, 93 kind: u32, 94 content: String, 95 tags: Vec<Vec<String>>, 96 ) -> Result<RadrootsParsedData<RadrootsFarm>, EventParseError> { 97 let farm = farm_from_event(kind, &tags, &content)?; 98 Ok(RadrootsParsedData::new( 99 id, 100 author, 101 published_at, 102 kind, 103 farm, 104 )) 105 } 106 107 pub fn parsed_from_event( 108 id: String, 109 author: String, 110 published_at: u32, 111 kind: u32, 112 content: String, 113 tags: Vec<Vec<String>>, 114 sig: String, 115 ) -> Result<RadrootsParsedEvent<RadrootsFarm>, EventParseError> { 116 let data = data_from_event( 117 id.clone(), 118 author.clone(), 119 published_at, 120 kind, 121 content.clone(), 122 tags.clone(), 123 )?; 124 Ok(RadrootsParsedEvent { 125 event: RadrootsNostrEvent { 126 id, 127 author, 128 created_at: published_at, 129 kind, 130 content, 131 tags, 132 sig, 133 }, 134 data, 135 }) 136 }