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