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 }