encode.rs (3184B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{ 3 string::{String, ToString}, 4 vec, 5 vec::Vec, 6 }; 7 8 use radroots_event::{ 9 envelope::kind::KIND_FARM, 10 farm::location::{has_textual_locality, is_public_geohash5}, 11 farm::{Farm, FarmRef}, 12 tag::name::TAG_D, 13 }; 14 15 use crate::d_tag::validate_d_tag; 16 use crate::error::EventEncodeError; 17 18 #[cfg(feature = "json")] 19 use radroots_event::wire::Nip01EventWireParts; 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 farm_build_tags(farm: &Farm) -> Result<Vec<Vec<String>>, EventEncodeError> { 29 if farm.d_tag.trim().is_empty() { 30 return Err(EventEncodeError::EmptyRequiredField("d_tag")); 31 } 32 validate_d_tag(&farm.d_tag, "d_tag")?; 33 if farm.name.trim().is_empty() { 34 return Err(EventEncodeError::EmptyRequiredField("name")); 35 } 36 let mut tags = Vec::new(); 37 push_tag(&mut tags, TAG_D, &farm.d_tag); 38 if let Some(items) = farm.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) = farm.location.as_ref() { 44 if !has_textual_locality( 45 &location.primary, 46 location.city.as_deref(), 47 location.region.as_deref(), 48 location.country.as_deref(), 49 ) { 50 return Err(EventEncodeError::EmptyRequiredField("location.locality")); 51 } 52 let geohash = location.geohash.trim(); 53 if geohash.is_empty() { 54 return Err(EventEncodeError::EmptyRequiredField("location.geohash")); 55 } 56 if !is_public_geohash5(geohash) { 57 return Err(EventEncodeError::InvalidField("location.geohash")); 58 } 59 push_tag(&mut tags, TAG_G, geohash); 60 } 61 Ok(tags) 62 } 63 64 pub fn farm_ref_tags(farm: &FarmRef) -> Result<Vec<Vec<String>>, EventEncodeError> { 65 if farm.pubkey.trim().is_empty() { 66 return Err(EventEncodeError::EmptyRequiredField("farm.pubkey")); 67 } 68 if farm.d_tag.trim().is_empty() { 69 return Err(EventEncodeError::EmptyRequiredField("farm.d_tag")); 70 } 71 validate_d_tag(&farm.d_tag, "farm.d_tag")?; 72 let mut addr = String::new(); 73 addr.push_str(&KIND_FARM.to_string()); 74 addr.push(':'); 75 addr.push_str(&farm.pubkey); 76 addr.push(':'); 77 addr.push_str(&farm.d_tag); 78 let mut tags = Vec::with_capacity(2); 79 push_tag(&mut tags, "p", &farm.pubkey); 80 push_tag(&mut tags, "a", &addr); 81 Ok(tags) 82 } 83 84 #[cfg(feature = "json")] 85 pub fn to_wire_parts(farm: &Farm) -> Result<Nip01EventWireParts, EventEncodeError> { 86 to_wire_parts_with_kind(farm, KIND_FARM) 87 } 88 89 #[cfg(feature = "json")] 90 pub fn to_wire_parts_with_kind( 91 farm: &Farm, 92 kind: u32, 93 ) -> Result<Nip01EventWireParts, EventEncodeError> { 94 if kind != KIND_FARM { 95 return Err(EventEncodeError::InvalidKind(kind)); 96 } 97 let tags = farm_build_tags(farm)?; 98 let content = serde_json::to_string(farm).map_err(|_| EventEncodeError::Json)?; 99 Ok(Nip01EventWireParts { 100 kind, 101 content, 102 tags, 103 }) 104 }