parsed.rs (5441B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{string::String, vec::Vec}; 3 4 use crate::error::EventParseError; 5 use radroots_event::{envelope::EventEnvelope, envelope::EventEnvelopeParts}; 6 7 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 8 #[derive(Clone, Debug, PartialEq, Eq)] 9 pub struct RadrootsParsedData<T> { 10 pub id: String, 11 pub author: String, 12 pub published_at: u64, 13 pub kind: u32, 14 pub data: T, 15 } 16 17 impl<T> RadrootsParsedData<T> { 18 #[inline] 19 pub fn new(id: String, author: String, published_at: u64, kind: u32, data: T) -> Self { 20 Self { 21 id, 22 author, 23 published_at, 24 kind, 25 data, 26 } 27 } 28 } 29 30 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 31 #[derive(Clone, Debug)] 32 pub struct RadrootsParsedEvent<T> { 33 pub event: EventEnvelope, 34 pub data: RadrootsParsedData<T>, 35 } 36 37 impl<T> RadrootsParsedEvent<T> { 38 #[inline] 39 pub fn new(event: EventEnvelope, data: RadrootsParsedData<T>) -> Self { 40 Self { event, data } 41 } 42 43 #[allow(clippy::too_many_arguments)] 44 pub fn from_parts( 45 id: String, 46 author: String, 47 published_at: u64, 48 kind: u32, 49 content: String, 50 tags: Vec<Vec<String>>, 51 sig: String, 52 data: T, 53 ) -> Result<Self, EventParseError> { 54 let parsed_data = 55 RadrootsParsedData::new(id.clone(), author.clone(), published_at, kind, data); 56 Self::from_event_parts( 57 id, 58 author, 59 published_at, 60 kind, 61 content, 62 tags, 63 sig, 64 parsed_data, 65 ) 66 } 67 68 #[allow(clippy::too_many_arguments)] 69 pub fn from_event_parts( 70 id: String, 71 author: String, 72 published_at: u64, 73 kind: u32, 74 content: String, 75 tags: Vec<Vec<String>>, 76 sig: String, 77 data: RadrootsParsedData<T>, 78 ) -> Result<Self, EventParseError> { 79 let event = EventEnvelope::new(EventEnvelopeParts { 80 id, 81 author, 82 created_at: published_at, 83 kind, 84 tags, 85 content, 86 sig, 87 })?; 88 Ok(Self { event, data }) 89 } 90 } 91 92 #[cfg(test)] 93 mod tests { 94 use super::{RadrootsParsedData, RadrootsParsedEvent}; 95 use radroots_event::{envelope::EventEnvelope, envelope::EventEnvelopeParts}; 96 97 const EVENT_ID: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 98 const AUTHOR: &str = crate::test_fixtures::FIXTURE_ALICE_PUBLIC_KEY_HEX; 99 const SIG: &str = concat!( 100 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", 101 "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" 102 ); 103 104 #[test] 105 fn parsed_data_constructor_maps_fields() { 106 let out = RadrootsParsedData::new( 107 "id".to_string(), 108 "author".to_string(), 109 10, 110 30402, 111 "payload".to_string(), 112 ); 113 assert_eq!(out.id, "id"); 114 assert_eq!(out.author, "author"); 115 assert_eq!(out.published_at, 10); 116 assert_eq!(out.kind, 30402); 117 assert_eq!(out.data, "payload"); 118 } 119 120 #[test] 121 fn parsed_event_constructor_maps_event_and_data() { 122 let event = EventEnvelope::new(EventEnvelopeParts { 123 id: EVENT_ID.to_string(), 124 author: AUTHOR.to_string(), 125 created_at: 22, 126 kind: 1, 127 tags: vec![vec!["k".to_string(), "v".to_string()]], 128 content: "content".to_string(), 129 sig: SIG.to_string(), 130 }) 131 .unwrap(); 132 let data = RadrootsParsedData::new( 133 EVENT_ID.to_string(), 134 AUTHOR.to_string(), 135 22, 136 1, 137 "payload".to_string(), 138 ); 139 140 let out = RadrootsParsedEvent::new(event.clone(), data.clone()); 141 assert_eq!(out.event.id(), event.id()); 142 assert_eq!(out.event.author(), event.author()); 143 assert_eq!(out.event.created_at(), event.created_at()); 144 assert_eq!(out.event.kind(), event.kind()); 145 assert_eq!(out.event.tags(), event.tags()); 146 assert_eq!(out.event.content(), event.content()); 147 assert_eq!(out.event.sig(), event.sig()); 148 assert_eq!(out.data, data); 149 } 150 151 #[test] 152 fn parsed_event_from_parts_builds_consistent_structs() { 153 let out = RadrootsParsedEvent::from_parts( 154 EVENT_ID.to_string(), 155 AUTHOR.to_string(), 156 77, 157 1111, 158 "hello".to_string(), 159 vec![vec!["e".to_string(), "root".to_string()]], 160 SIG.to_string(), 161 "payload".to_string(), 162 ) 163 .unwrap(); 164 assert_eq!(out.event.id_hex(), EVENT_ID); 165 assert_eq!(out.event.author().to_hex(), AUTHOR); 166 assert_eq!(out.event.created_at_u64(), 77); 167 assert_eq!(out.event.kind_u32(), 1111); 168 assert_eq!(out.event.content(), "hello"); 169 assert_eq!( 170 out.event.tags_as_vec(), 171 vec![vec!["e".to_string(), "root".to_string()]] 172 ); 173 assert_eq!(out.event.signature_hex(), SIG); 174 assert_eq!(out.data.id, EVENT_ID); 175 assert_eq!(out.data.author, AUTHOR); 176 assert_eq!(out.data.published_at, 77); 177 assert_eq!(out.data.kind, 1111); 178 assert_eq!(out.data.data, "payload"); 179 } 180 }