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