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