lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

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 }