encode.rs (3023B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{ 3 string::{String, ToString}, 4 vec::Vec, 5 }; 6 7 use radroots_events::{ 8 kinds::KIND_RESOURCE_AREA, 9 resource_area::{RadrootsResourceArea, RadrootsResourceAreaRef}, 10 tags::TAG_D, 11 }; 12 13 use crate::d_tag::validate_d_tag; 14 use crate::error::EventEncodeError; 15 16 #[cfg(feature = "serde_json")] 17 use crate::wire::WireEventParts; 18 19 const TAG_T: &str = "t"; 20 const TAG_G: &str = "g"; 21 const TAG_A: &str = "a"; 22 const TAG_P: &str = "p"; 23 24 fn push_tag(tags: &mut Vec<Vec<String>>, key: &str, value: &str) { 25 tags.push(vec![key.to_string(), value.to_string()]); 26 } 27 28 fn resource_area_address(area: &RadrootsResourceAreaRef) -> Result<String, EventEncodeError> { 29 if area.pubkey.trim().is_empty() { 30 return Err(EventEncodeError::EmptyRequiredField("resource_area.pubkey")); 31 } 32 if area.d_tag.trim().is_empty() { 33 return Err(EventEncodeError::EmptyRequiredField("resource_area.d_tag")); 34 } 35 validate_d_tag(&area.d_tag, "resource_area.d_tag")?; 36 let mut addr = String::new(); 37 addr.push_str(&KIND_RESOURCE_AREA.to_string()); 38 addr.push(':'); 39 addr.push_str(&area.pubkey); 40 addr.push(':'); 41 addr.push_str(&area.d_tag); 42 Ok(addr) 43 } 44 45 pub fn resource_area_build_tags( 46 area: &RadrootsResourceArea, 47 ) -> Result<Vec<Vec<String>>, EventEncodeError> { 48 if area.d_tag.trim().is_empty() { 49 return Err(EventEncodeError::EmptyRequiredField("d_tag")); 50 } 51 validate_d_tag(&area.d_tag, "d_tag")?; 52 if area.name.trim().is_empty() { 53 return Err(EventEncodeError::EmptyRequiredField("name")); 54 } 55 let geohash = area.location.gcs.geohash.trim(); 56 if geohash.is_empty() { 57 return Err(EventEncodeError::EmptyRequiredField("location.gcs.geohash")); 58 } 59 let mut tags = Vec::new(); 60 push_tag(&mut tags, TAG_D, &area.d_tag); 61 if let Some(items) = area.tags.as_ref() { 62 for item in items.iter().filter(|v| !v.trim().is_empty()) { 63 push_tag(&mut tags, TAG_T, item); 64 } 65 } 66 push_tag(&mut tags, TAG_G, geohash); 67 Ok(tags) 68 } 69 70 pub fn resource_area_ref_tags( 71 area: &RadrootsResourceAreaRef, 72 ) -> Result<Vec<Vec<String>>, EventEncodeError> { 73 let addr = resource_area_address(area)?; 74 let mut tags = Vec::with_capacity(2); 75 push_tag(&mut tags, TAG_P, &area.pubkey); 76 push_tag(&mut tags, TAG_A, &addr); 77 Ok(tags) 78 } 79 80 #[cfg(feature = "serde_json")] 81 pub fn to_wire_parts(area: &RadrootsResourceArea) -> Result<WireEventParts, EventEncodeError> { 82 to_wire_parts_with_kind(area, KIND_RESOURCE_AREA) 83 } 84 85 #[cfg(feature = "serde_json")] 86 pub fn to_wire_parts_with_kind( 87 area: &RadrootsResourceArea, 88 kind: u32, 89 ) -> Result<WireEventParts, EventEncodeError> { 90 if kind != KIND_RESOURCE_AREA { 91 return Err(EventEncodeError::InvalidKind(kind)); 92 } 93 let tags = resource_area_build_tags(area)?; 94 let content = serde_json::to_string(area).map_err(|_| EventEncodeError::Json)?; 95 Ok(WireEventParts { 96 kind, 97 content, 98 tags, 99 }) 100 }