lib

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

decode.rs (3049B)


      1 use radroots_event::{
      2     envelope::kind::is_result_kind, social::job::JobPaymentRequest, social::job_request::JobInput,
      3     social::job_result::JobResult, tag::EventPtr,
      4 };
      5 
      6 #[cfg(not(feature = "std"))]
      7 use alloc::{
      8     string::{String, ToString},
      9     vec::Vec,
     10 };
     11 
     12 use crate::job::{
     13     error::JobParseError,
     14     util::{parse_amount_tag_sat, parse_bool_encrypted, parse_i_tags},
     15 };
     16 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent};
     17 
     18 pub fn job_result_from_tags(
     19     kind: u32,
     20     tags: &[Vec<String>],
     21     content: &str,
     22 ) -> Result<JobResult, JobParseError> {
     23     let kind = u16::try_from(kind).map_err(|_| JobParseError::KindOutOfRange(kind))?;
     24     let etag = tags
     25         .iter()
     26         .find(|t| t.first().map(|s| s.as_str()) == Some("e"))
     27         .or_else(|| {
     28             tags.iter()
     29                 .find(|t| t.first().map(|s| s.as_str()) == Some("e_ref"))
     30         })
     31         .ok_or(JobParseError::MissingTag("e"))?;
     32 
     33     let req_id = etag.get(1).ok_or(JobParseError::InvalidTag("e"))?.clone();
     34     let relay_hint = etag.get(2).cloned();
     35 
     36     let request_json = tags
     37         .iter()
     38         .find(|t| t.first().map(|s| s.as_str()) == Some("request"))
     39         .and_then(|t| t.get(1).cloned());
     40 
     41     let inputs: Vec<JobInput> = parse_i_tags(tags);
     42 
     43     let payment = parse_amount_tag_sat(tags)?.map(|(sat, bolt11)| JobPaymentRequest {
     44         amount_sat: sat,
     45         bolt11,
     46     });
     47 
     48     let encrypted = parse_bool_encrypted(tags);
     49 
     50     let customer_pubkey = tags
     51         .iter()
     52         .find(|t| t.first().map(|s| s.as_str()) == Some("p"))
     53         .and_then(|t| t.get(1).cloned());
     54 
     55     Ok(JobResult {
     56         kind,
     57         request_event: EventPtr {
     58             id: req_id,
     59             relays: relay_hint,
     60         },
     61         request_json,
     62         inputs,
     63         customer_pubkey,
     64         payment,
     65         content: if content.is_empty() {
     66             None
     67         } else {
     68             Some(content.to_string())
     69         },
     70         encrypted,
     71     })
     72 }
     73 
     74 pub fn data_from_event(
     75     id: String,
     76     author: String,
     77     published_at: u64,
     78     kind: u32,
     79     content: String,
     80     tags: Vec<Vec<String>>,
     81 ) -> Result<RadrootsParsedData<JobResult>, JobParseError> {
     82     if !is_result_kind(kind) {
     83         return Err(JobParseError::InvalidTag("kind (expected 6000-6999)"));
     84     }
     85     let job_result = job_result_from_tags(kind, &tags, &content)?;
     86     Ok(RadrootsParsedData::new(
     87         id,
     88         author,
     89         published_at,
     90         kind,
     91         job_result,
     92     ))
     93 }
     94 
     95 pub fn parsed_from_event(
     96     id: String,
     97     author: String,
     98     published_at: u64,
     99     kind: u32,
    100     content: String,
    101     tags: Vec<Vec<String>>,
    102     sig: String,
    103 ) -> Result<RadrootsParsedEvent<JobResult>, JobParseError> {
    104     let data = data_from_event(
    105         id.clone(),
    106         author.clone(),
    107         published_at,
    108         kind,
    109         content.clone(),
    110         tags.clone(),
    111     )?;
    112     RadrootsParsedEvent::from_event_parts(id, author, published_at, kind, content, tags, sig, data)
    113         .map_err(|_| JobParseError::InvalidTag("event_envelope"))
    114 }