encode.rs (2720B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{ 3 string::{String, ToString}, 4 vec, 5 vec::Vec, 6 }; 7 8 use radroots_event::social::list_set::ListSet; 9 10 use crate::error::EventEncodeError; 11 #[cfg(feature = "json")] 12 use crate::list::encode::list_entries_to_tags; 13 use radroots_event::wire::Nip01EventWireParts; 14 15 const TAG_D: &str = "d"; 16 const TAG_TITLE: &str = "title"; 17 const TAG_DESCRIPTION: &str = "description"; 18 const TAG_IMAGE: &str = "image"; 19 20 fn push_tag(tags: &mut Vec<Vec<String>>, key: &str, value: &str) { 21 tags.push(vec![key.to_string(), value.to_string()]); 22 } 23 24 pub fn list_set_build_tags(list: &ListSet) -> Result<Vec<Vec<String>>, EventEncodeError> { 25 if list.d_tag.trim().is_empty() { 26 return Err(EventEncodeError::EmptyRequiredField("d_tag")); 27 } 28 if !super::list_set_base64_id_is_valid(&list.d_tag) { 29 return Err(EventEncodeError::InvalidField("d_tag")); 30 } 31 let mut tags = Vec::with_capacity(1 + list.entries.len() + 3); 32 push_tag(&mut tags, TAG_D, &list.d_tag); 33 if let Some(title) = list.title.as_ref().filter(|v| !v.trim().is_empty()) { 34 push_tag(&mut tags, TAG_TITLE, title); 35 } 36 if let Some(description) = list.description.as_ref().filter(|v| !v.trim().is_empty()) { 37 push_tag(&mut tags, TAG_DESCRIPTION, description); 38 } 39 if let Some(image) = list.image.as_ref().filter(|v| !v.trim().is_empty()) { 40 push_tag(&mut tags, TAG_IMAGE, image); 41 } 42 for entry in &list.entries { 43 if entry.tag.trim().is_empty() { 44 return Err(EventEncodeError::EmptyRequiredField("entry.tag")); 45 } 46 let first = entry 47 .values 48 .first() 49 .ok_or(EventEncodeError::EmptyRequiredField("entry.values"))?; 50 if first.trim().is_empty() { 51 return Err(EventEncodeError::EmptyRequiredField("entry.values")); 52 } 53 let mut tag = Vec::with_capacity(1 + entry.values.len()); 54 tag.push(entry.tag.clone()); 55 tag.extend(entry.values.iter().cloned()); 56 tags.push(tag); 57 } 58 Ok(tags) 59 } 60 61 pub fn to_wire_parts_with_kind( 62 list: &ListSet, 63 kind: u32, 64 ) -> Result<Nip01EventWireParts, EventEncodeError> { 65 if !super::is_generic_list_set_codec_kind(kind) { 66 return Err(EventEncodeError::InvalidKind(kind)); 67 } 68 let tags = list_set_build_tags(list)?; 69 Ok(Nip01EventWireParts { 70 kind, 71 content: list.content.clone(), 72 tags, 73 }) 74 } 75 76 #[cfg(feature = "json")] 77 pub fn list_set_private_entries_json( 78 entries: &[radroots_event::social::list::ListEntry], 79 ) -> Result<String, EventEncodeError> { 80 let tags = list_entries_to_tags(entries)?; 81 serde_json::to_string(&tags).map_err(|_| EventEncodeError::Json) 82 }