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