lib

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

encode.rs (3184B)


      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_FARM,
     10     farm::location::{has_textual_locality, is_public_geohash5},
     11     farm::{Farm, FarmRef},
     12     tag::name::TAG_D,
     13 };
     14 
     15 use crate::d_tag::validate_d_tag;
     16 use crate::error::EventEncodeError;
     17 
     18 #[cfg(feature = "json")]
     19 use radroots_event::wire::Nip01EventWireParts;
     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 farm_build_tags(farm: &Farm) -> Result<Vec<Vec<String>>, EventEncodeError> {
     29     if farm.d_tag.trim().is_empty() {
     30         return Err(EventEncodeError::EmptyRequiredField("d_tag"));
     31     }
     32     validate_d_tag(&farm.d_tag, "d_tag")?;
     33     if farm.name.trim().is_empty() {
     34         return Err(EventEncodeError::EmptyRequiredField("name"));
     35     }
     36     let mut tags = Vec::new();
     37     push_tag(&mut tags, TAG_D, &farm.d_tag);
     38     if let Some(items) = farm.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) = farm.location.as_ref() {
     44         if !has_textual_locality(
     45             &location.primary,
     46             location.city.as_deref(),
     47             location.region.as_deref(),
     48             location.country.as_deref(),
     49         ) {
     50             return Err(EventEncodeError::EmptyRequiredField("location.locality"));
     51         }
     52         let geohash = location.geohash.trim();
     53         if geohash.is_empty() {
     54             return Err(EventEncodeError::EmptyRequiredField("location.geohash"));
     55         }
     56         if !is_public_geohash5(geohash) {
     57             return Err(EventEncodeError::InvalidField("location.geohash"));
     58         }
     59         push_tag(&mut tags, TAG_G, geohash);
     60     }
     61     Ok(tags)
     62 }
     63 
     64 pub fn farm_ref_tags(farm: &FarmRef) -> Result<Vec<Vec<String>>, EventEncodeError> {
     65     if farm.pubkey.trim().is_empty() {
     66         return Err(EventEncodeError::EmptyRequiredField("farm.pubkey"));
     67     }
     68     if farm.d_tag.trim().is_empty() {
     69         return Err(EventEncodeError::EmptyRequiredField("farm.d_tag"));
     70     }
     71     validate_d_tag(&farm.d_tag, "farm.d_tag")?;
     72     let mut addr = String::new();
     73     addr.push_str(&KIND_FARM.to_string());
     74     addr.push(':');
     75     addr.push_str(&farm.pubkey);
     76     addr.push(':');
     77     addr.push_str(&farm.d_tag);
     78     let mut tags = Vec::with_capacity(2);
     79     push_tag(&mut tags, "p", &farm.pubkey);
     80     push_tag(&mut tags, "a", &addr);
     81     Ok(tags)
     82 }
     83 
     84 #[cfg(feature = "json")]
     85 pub fn to_wire_parts(farm: &Farm) -> Result<Nip01EventWireParts, EventEncodeError> {
     86     to_wire_parts_with_kind(farm, KIND_FARM)
     87 }
     88 
     89 #[cfg(feature = "json")]
     90 pub fn to_wire_parts_with_kind(
     91     farm: &Farm,
     92     kind: u32,
     93 ) -> Result<Nip01EventWireParts, EventEncodeError> {
     94     if kind != KIND_FARM {
     95         return Err(EventEncodeError::InvalidKind(kind));
     96     }
     97     let tags = farm_build_tags(farm)?;
     98     let content = serde_json::to_string(farm).map_err(|_| EventEncodeError::Json)?;
     99     Ok(Nip01EventWireParts {
    100         kind,
    101         content,
    102         tags,
    103     })
    104 }