lib

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

encode.rs (2751B)


      1 #![forbid(unsafe_code)]
      2 
      3 #[cfg(not(feature = "std"))]
      4 use alloc::{
      5     string::{String, ToString},
      6     vec::Vec,
      7 };
      8 
      9 use radroots_events::{
     10     coop::{RadrootsCoop, RadrootsCoopRef},
     11     kinds::KIND_COOP,
     12     tags::TAG_D,
     13 };
     14 
     15 use crate::d_tag::validate_d_tag;
     16 use crate::error::EventEncodeError;
     17 
     18 #[cfg(feature = "serde_json")]
     19 use crate::wire::WireEventParts;
     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 coop_build_tags(coop: &RadrootsCoop) -> Result<Vec<Vec<String>>, EventEncodeError> {
     29     if coop.d_tag.trim().is_empty() {
     30         return Err(EventEncodeError::EmptyRequiredField("d_tag"));
     31     }
     32     validate_d_tag(&coop.d_tag, "d_tag")?;
     33     if coop.name.trim().is_empty() {
     34         return Err(EventEncodeError::EmptyRequiredField("name"));
     35     }
     36     let mut tags = Vec::new();
     37     push_tag(&mut tags, TAG_D, &coop.d_tag);
     38     if let Some(items) = coop.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) = coop.location.as_ref() {
     44         let geohash = location.gcs.geohash.trim();
     45         if geohash.is_empty() {
     46             return Err(EventEncodeError::EmptyRequiredField("location.gcs.geohash"));
     47         }
     48         push_tag(&mut tags, TAG_G, geohash);
     49     }
     50     Ok(tags)
     51 }
     52 
     53 pub fn coop_ref_tags(coop: &RadrootsCoopRef) -> Result<Vec<Vec<String>>, EventEncodeError> {
     54     if coop.pubkey.trim().is_empty() {
     55         return Err(EventEncodeError::EmptyRequiredField("coop.pubkey"));
     56     }
     57     if coop.d_tag.trim().is_empty() {
     58         return Err(EventEncodeError::EmptyRequiredField("coop.d_tag"));
     59     }
     60     validate_d_tag(&coop.d_tag, "coop.d_tag")?;
     61     let mut addr = String::new();
     62     addr.push_str(&KIND_COOP.to_string());
     63     addr.push(':');
     64     addr.push_str(&coop.pubkey);
     65     addr.push(':');
     66     addr.push_str(&coop.d_tag);
     67     let mut tags = Vec::with_capacity(2);
     68     push_tag(&mut tags, "p", &coop.pubkey);
     69     push_tag(&mut tags, "a", &addr);
     70     Ok(tags)
     71 }
     72 
     73 #[cfg(feature = "serde_json")]
     74 pub fn to_wire_parts(coop: &RadrootsCoop) -> Result<WireEventParts, EventEncodeError> {
     75     to_wire_parts_with_kind(coop, KIND_COOP)
     76 }
     77 
     78 #[cfg(feature = "serde_json")]
     79 pub fn to_wire_parts_with_kind(
     80     coop: &RadrootsCoop,
     81     kind: u32,
     82 ) -> Result<WireEventParts, EventEncodeError> {
     83     if kind != KIND_COOP {
     84         return Err(EventEncodeError::InvalidKind(kind));
     85     }
     86     let tags = coop_build_tags(coop)?;
     87     let content = serde_json::to_string(coop).map_err(|_| EventEncodeError::Json)?;
     88     Ok(WireEventParts {
     89         kind,
     90         content,
     91         tags,
     92     })
     93 }