lib

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

decode.rs (2668B)


      1 #[cfg(not(feature = "std"))]
      2 use alloc::{string::String, vec::Vec};
      3 
      4 use radroots_event::{
      5     envelope::kind::KIND_FOLLOW,
      6     social::follow::{Follow, FollowProfile},
      7 };
      8 
      9 use crate::error::EventParseError;
     10 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent};
     11 
     12 const DEFAULT_KIND: u32 = KIND_FOLLOW;
     13 
     14 fn looks_like_ws_relay(s: &str) -> bool {
     15     s.starts_with("ws://") || s.starts_with("wss://")
     16 }
     17 
     18 fn parse_follow_tag(tag: &[String], published_at: u64) -> Result<FollowProfile, EventParseError> {
     19     let public_key = tag.get(1).ok_or(EventParseError::InvalidTag("p"))?;
     20     let (relay_url, contact_name) = match tag.get(2).filter(|s| !s.is_empty()) {
     21         Some(value) if looks_like_ws_relay(value) => (
     22             Some(value.clone()),
     23             tag.get(3).filter(|s| !s.is_empty()).cloned(),
     24         ),
     25         Some(value) => (None, Some(value.clone())),
     26         None => (None, tag.get(3).filter(|s| !s.is_empty()).cloned()),
     27     };
     28 
     29     let published_at = match tag.get(4) {
     30         Some(v) => v
     31             .parse()
     32             .map_err(|e| EventParseError::InvalidNumber("p", e))?,
     33         None => published_at,
     34     };
     35 
     36     Ok(FollowProfile {
     37         published_at,
     38         public_key: public_key.clone(),
     39         relay_url,
     40         contact_name,
     41     })
     42 }
     43 
     44 pub fn follow_from_tags(
     45     kind: u32,
     46     tags: &[Vec<String>],
     47     published_at: u64,
     48 ) -> Result<Follow, EventParseError> {
     49     if kind != DEFAULT_KIND {
     50         return Err(EventParseError::InvalidKind {
     51             expected: "3",
     52             got: kind,
     53         });
     54     }
     55     let mut list = Vec::new();
     56     for tag in tags
     57         .iter()
     58         .filter(|t| t.first().map(|s| s.as_str()) == Some("p"))
     59     {
     60         list.push(parse_follow_tag(tag, published_at)?);
     61     }
     62     Ok(Follow { list })
     63 }
     64 
     65 pub fn data_from_event(
     66     id: String,
     67     author: String,
     68     published_at: u64,
     69     kind: u32,
     70     _content: String,
     71     tags: Vec<Vec<String>>,
     72 ) -> Result<RadrootsParsedData<Follow>, EventParseError> {
     73     let follow = follow_from_tags(kind, &tags, published_at)?;
     74     Ok(RadrootsParsedData::new(
     75         id,
     76         author,
     77         published_at,
     78         kind,
     79         follow,
     80     ))
     81 }
     82 
     83 pub fn parsed_from_event(
     84     id: String,
     85     author: String,
     86     published_at: u64,
     87     kind: u32,
     88     content: String,
     89     tags: Vec<Vec<String>>,
     90     sig: String,
     91 ) -> Result<RadrootsParsedEvent<Follow>, EventParseError> {
     92     let data = data_from_event(
     93         id.clone(),
     94         author.clone(),
     95         published_at,
     96         kind,
     97         content.clone(),
     98         tags.clone(),
     99     )?;
    100     RadrootsParsedEvent::from_event_parts(id, author, published_at, kind, content, tags, sig, data)
    101 }