lib

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

decode.rs (3235B)


      1 use radroots_event::{
      2     envelope::kind::KIND_JOB_FEEDBACK, social::job::JobPaymentRequest,
      3     social::job_feedback::JobFeedback, 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::{feedback_status_from_tag, parse_amount_tag_sat, parse_bool_encrypted},
     15 };
     16 use crate::parsed::{RadrootsParsedData, RadrootsParsedEvent};
     17 
     18 pub fn job_feedback_from_tags(
     19     kind: u32,
     20     tags: &[Vec<String>],
     21     content: &str,
     22 ) -> Result<JobFeedback, 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     let req_id = etag.get(1).ok_or(JobParseError::InvalidTag("e"))?.clone();
     33     let relay_hint = etag.get(2).cloned();
     34 
     35     let status_tag = tags
     36         .iter()
     37         .find(|t| t.first().map(|s| s.as_str()) == Some("status"))
     38         .ok_or(JobParseError::MissingTag("status"))?;
     39 
     40     let status = match status_tag.get(1).and_then(|s| feedback_status_from_tag(s)) {
     41         Some(s) => s,
     42         None => return Err(JobParseError::InvalidTag("status")),
     43     };
     44 
     45     let extra_info = status_tag.get(2).cloned();
     46 
     47     let payment = parse_amount_tag_sat(tags)?.map(|(sat, bolt11)| JobPaymentRequest {
     48         amount_sat: sat,
     49         bolt11,
     50     });
     51 
     52     let encrypted = parse_bool_encrypted(tags);
     53 
     54     let customer_pubkey = tags
     55         .iter()
     56         .find(|t| t.first().map(|s| s.as_str()) == Some("p"))
     57         .and_then(|t| t.get(1).cloned());
     58 
     59     Ok(JobFeedback {
     60         kind,
     61         status,
     62         extra_info,
     63         request_event: EventPtr {
     64             id: req_id,
     65             relays: relay_hint,
     66         },
     67         customer_pubkey,
     68         payment,
     69         content: if content.is_empty() {
     70             None
     71         } else {
     72             Some(content.to_string())
     73         },
     74         encrypted,
     75     })
     76 }
     77 
     78 pub fn data_from_event(
     79     id: String,
     80     author: String,
     81     published_at: u64,
     82     kind: u32,
     83     content: String,
     84     tags: Vec<Vec<String>>,
     85 ) -> Result<RadrootsParsedData<JobFeedback>, JobParseError> {
     86     if kind != KIND_JOB_FEEDBACK {
     87         return Err(JobParseError::InvalidTag("kind (expected 7000)"));
     88     }
     89     let job_feedback = job_feedback_from_tags(kind, &tags, &content)?;
     90     Ok(RadrootsParsedData::new(
     91         id,
     92         author,
     93         published_at,
     94         kind,
     95         job_feedback,
     96     ))
     97 }
     98 
     99 pub fn parsed_from_event(
    100     id: String,
    101     author: String,
    102     published_at: u64,
    103     kind: u32,
    104     content: String,
    105     tags: Vec<Vec<String>>,
    106     sig: String,
    107 ) -> Result<RadrootsParsedEvent<JobFeedback>, JobParseError> {
    108     let data = data_from_event(
    109         id.clone(),
    110         author.clone(),
    111         published_at,
    112         kind,
    113         content.clone(),
    114         tags.clone(),
    115     )?;
    116     RadrootsParsedEvent::from_event_parts(id, author, published_at, kind, content, tags, sig, data)
    117         .map_err(|_| JobParseError::InvalidTag("event_envelope"))
    118 }