lib

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

decode.rs (3295B)


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