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 }