lib

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

decode.rs (2896B)


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