lib

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

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 }