lib

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

encode.rs (3514B)


      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_events::kinds::KIND_MESSAGE_FILE;
     11 use radroots_events::message_file::{RadrootsMessageFile, RadrootsMessageFileDimensions};
     12 
     13 use crate::error::EventEncodeError;
     14 use crate::message::tags::{build_recipient_tags, build_reply_tag, build_subject_tag};
     15 use crate::wire::WireEventParts;
     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(
     44     tags: &mut Vec<Vec<String>>,
     45     dimensions: &Option<RadrootsMessageFileDimensions>,
     46 ) {
     47     if let Some(dimensions) = dimensions {
     48         tags.push(vec![
     49             "dim".to_string(),
     50             format!("{}x{}", dimensions.w, dimensions.h),
     51         ]);
     52     }
     53 }
     54 
     55 pub fn message_file_build_tags(
     56     message: &RadrootsMessageFile,
     57 ) -> Result<Vec<Vec<String>>, EventEncodeError> {
     58     let mut tags = build_recipient_tags(&message.recipients)?;
     59     if let Some(tag) = build_reply_tag(&message.reply_to)? {
     60         tags.push(tag);
     61     }
     62     if let Some(tag) = build_subject_tag(&message.subject)? {
     63         tags.push(tag);
     64     }
     65 
     66     push_required_tag(&mut tags, "file-type", &message.file_type, "file_type")?;
     67     push_required_tag(
     68         &mut tags,
     69         "encryption-algorithm",
     70         &message.encryption_algorithm,
     71         "encryption_algorithm",
     72     )?;
     73     push_required_tag(
     74         &mut tags,
     75         "decryption-key",
     76         &message.decryption_key,
     77         "decryption_key",
     78     )?;
     79     push_required_tag(
     80         &mut tags,
     81         "decryption-nonce",
     82         &message.decryption_nonce,
     83         "decryption_nonce",
     84     )?;
     85     push_required_tag(&mut tags, "x", &message.encrypted_hash, "encrypted_hash")?;
     86 
     87     push_optional_tag(&mut tags, "ox", &message.original_hash);
     88     if let Some(size) = message.size {
     89         tags.push(vec!["size".to_string(), size.to_string()]);
     90     }
     91     push_dimensions_tag(&mut tags, &message.dimensions);
     92     push_optional_tag(&mut tags, "blurhash", &message.blurhash);
     93     push_optional_tag(&mut tags, "thumb", &message.thumb);
     94     for fallback in &message.fallbacks {
     95         validate_required(fallback, "fallback")?;
     96         tags.push(vec!["fallback".to_string(), fallback.clone()]);
     97     }
     98 
     99     Ok(tags)
    100 }
    101 
    102 pub fn to_wire_parts(message: &RadrootsMessageFile) -> Result<WireEventParts, EventEncodeError> {
    103     validate_required(&message.file_url, "file_url")?;
    104     let tags = message_file_build_tags(message)?;
    105     Ok(WireEventParts {
    106         kind: DEFAULT_KIND,
    107         content: message.file_url.clone(),
    108         tags,
    109     })
    110 }
    111 
    112 pub fn to_wire_parts_with_kind(
    113     message: &RadrootsMessageFile,
    114     kind: u32,
    115 ) -> Result<WireEventParts, EventEncodeError> {
    116     if kind != DEFAULT_KIND {
    117         return Err(EventEncodeError::InvalidKind(kind));
    118     }
    119     to_wire_parts(message)
    120 }