decode.rs (3298B)
1 use radroots_events::{ 2 RadrootsNostrEvent, RadrootsNostrEventPtr, job::JobPaymentRequest, 3 job_feedback::RadrootsJobFeedback, kinds::KIND_JOB_FEEDBACK, 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<RadrootsJobFeedback, JobParseError> { 23 let etag = tags 24 .iter() 25 .find(|t| t.first().map(|s| s.as_str()) == Some("e")) 26 .or_else(|| { 27 tags.iter() 28 .find(|t| t.first().map(|s| s.as_str()) == Some("e_ref")) 29 }) 30 .ok_or(JobParseError::MissingTag("e"))?; 31 let req_id = etag.get(1).ok_or(JobParseError::InvalidTag("e"))?.clone(); 32 let relay_hint = etag.get(2).cloned(); 33 34 let status_tag = tags 35 .iter() 36 .find(|t| t.first().map(|s| s.as_str()) == Some("status")) 37 .ok_or(JobParseError::MissingTag("status"))?; 38 39 let status = match status_tag.get(1).and_then(|s| feedback_status_from_tag(s)) { 40 Some(s) => s, 41 None => return Err(JobParseError::InvalidTag("status")), 42 }; 43 44 let extra_info = status_tag.get(2).cloned(); 45 46 let payment = parse_amount_tag_sat(tags)?.map(|(sat, bolt11)| JobPaymentRequest { 47 amount_sat: sat, 48 bolt11, 49 }); 50 51 let encrypted = parse_bool_encrypted(tags); 52 53 let customer_pubkey = tags 54 .iter() 55 .find(|t| t.first().map(|s| s.as_str()) == Some("p")) 56 .and_then(|t| t.get(1).cloned()); 57 58 Ok(RadrootsJobFeedback { 59 kind: kind as u16, 60 status, 61 extra_info, 62 request_event: RadrootsNostrEventPtr { 63 id: req_id, 64 relays: relay_hint, 65 }, 66 customer_pubkey, 67 payment, 68 content: if content.is_empty() { 69 None 70 } else { 71 Some(content.to_string()) 72 }, 73 encrypted, 74 }) 75 } 76 77 pub fn data_from_event( 78 id: String, 79 author: String, 80 published_at: u32, 81 kind: u32, 82 content: String, 83 tags: Vec<Vec<String>>, 84 ) -> Result<RadrootsParsedData<RadrootsJobFeedback>, JobParseError> { 85 if kind != KIND_JOB_FEEDBACK { 86 return Err(JobParseError::InvalidTag("kind (expected 7000)")); 87 } 88 let job_feedback = job_feedback_from_tags(kind, &tags, &content)?; 89 Ok(RadrootsParsedData::new( 90 id, 91 author, 92 published_at, 93 kind, 94 job_feedback, 95 )) 96 } 97 98 pub fn parsed_from_event( 99 id: String, 100 author: String, 101 published_at: u32, 102 kind: u32, 103 content: String, 104 tags: Vec<Vec<String>>, 105 sig: String, 106 ) -> Result<RadrootsParsedEvent<RadrootsJobFeedback>, JobParseError> { 107 let data = data_from_event( 108 id.clone(), 109 author.clone(), 110 published_at, 111 kind, 112 content.clone(), 113 tags.clone(), 114 )?; 115 Ok(RadrootsParsedEvent { 116 event: RadrootsNostrEvent { 117 id, 118 author, 119 created_at: published_at, 120 kind, 121 content, 122 tags, 123 sig, 124 }, 125 data, 126 }) 127 }