lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README

encode.rs (3499B)


      1 #[cfg(not(feature = "std"))]
      2 use alloc::vec;
      3 #[cfg(not(feature = "std"))]
      4 use alloc::{
      5     format,
      6     string::{String, ToString},
      7     vec::Vec,
      8 };
      9 
     10 use radroots_event::envelope::kind::KIND_MESSAGE_FILE;
     11 use radroots_event::social::message_file::{MessageFile, MessageFileDimensions};
     12 
     13 use crate::error::EventEncodeError;
     14 use crate::message::tags::{build_recipient_tags, build_reply_tag, build_subject_tag};
     15 use radroots_event::wire::Nip01EventWireParts;
     16 
     17 const DEFAULT_KIND: u32 = KIND_MESSAGE_FILE;
     18 
     19 fn validate_required(value: &str, field: &'static str) -> Result<(), EventEncodeError> {
     20     if value.trim().is_empty() {
     21         return Err(EventEncodeError::EmptyRequiredField(field));
     22     }
     23     Ok(())
     24 }
     25 
     26 fn push_required_tag(
     27     tags: &mut Vec<Vec<String>>,
     28     key: &'static str,
     29     value: &str,
     30     field: &'static str,
     31 ) -> Result<(), EventEncodeError> {
     32     validate_required(value, field)?;
     33     tags.push(vec![key.to_string(), value.to_string()]);
     34     Ok(())
     35 }
     36 
     37 fn push_optional_tag(tags: &mut Vec<Vec<String>>, key: &'static str, value: &Option<String>) {
     38     if let Some(value) = value {
     39         tags.push(vec![key.to_string(), value.clone()]);
     40     }
     41 }
     42 
     43 fn push_dimensions_tag(tags: &mut Vec<Vec<String>>, dimensions: &Option<MessageFileDimensions>) {
     44     if let Some(dimensions) = dimensions {
     45         tags.push(vec![
     46             "dim".to_string(),
     47             format!("{}x{}", dimensions.w, dimensions.h),
     48         ]);
     49     }
     50 }
     51 
     52 pub fn message_file_build_tags(
     53     message: &MessageFile,
     54 ) -> Result<Vec<Vec<String>>, EventEncodeError> {
     55     let mut tags = build_recipient_tags(&message.recipients)?;
     56     if let Some(tag) = build_reply_tag(&message.reply_to)? {
     57         tags.push(tag);
     58     }
     59     if let Some(tag) = build_subject_tag(&message.subject)? {
     60         tags.push(tag);
     61     }
     62 
     63     push_required_tag(&mut tags, "file-type", &message.file_type, "file_type")?;
     64     push_required_tag(
     65         &mut tags,
     66         "encryption-algorithm",
     67         &message.encryption_algorithm,
     68         "encryption_algorithm",
     69     )?;
     70     push_required_tag(
     71         &mut tags,
     72         "decryption-key",
     73         &message.decryption_key,
     74         "decryption_key",
     75     )?;
     76     push_required_tag(
     77         &mut tags,
     78         "decryption-nonce",
     79         &message.decryption_nonce,
     80         "decryption_nonce",
     81     )?;
     82     push_required_tag(&mut tags, "x", &message.encrypted_hash, "encrypted_hash")?;
     83 
     84     push_optional_tag(&mut tags, "ox", &message.original_hash);
     85     if let Some(size) = message.size {
     86         tags.push(vec!["size".to_string(), size.to_string()]);
     87     }
     88     push_dimensions_tag(&mut tags, &message.dimensions);
     89     push_optional_tag(&mut tags, "blurhash", &message.blurhash);
     90     push_optional_tag(&mut tags, "thumb", &message.thumb);
     91     for fallback in &message.fallbacks {
     92         validate_required(fallback, "fallback")?;
     93         tags.push(vec!["fallback".to_string(), fallback.clone()]);
     94     }
     95 
     96     Ok(tags)
     97 }
     98 
     99 pub fn to_wire_parts(message: &MessageFile) -> Result<Nip01EventWireParts, EventEncodeError> {
    100     validate_required(&message.file_url, "file_url")?;
    101     let tags = message_file_build_tags(message)?;
    102     Ok(Nip01EventWireParts {
    103         kind: DEFAULT_KIND,
    104         content: message.file_url.clone(),
    105         tags,
    106     })
    107 }
    108 
    109 pub fn to_wire_parts_with_kind(
    110     message: &MessageFile,
    111     kind: u32,
    112 ) -> Result<Nip01EventWireParts, EventEncodeError> {
    113     if kind != DEFAULT_KIND {
    114         return Err(EventEncodeError::InvalidKind(kind));
    115     }
    116     to_wire_parts(message)
    117 }