lib

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

encode.rs (3023B)


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