lib

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

encode.rs (3665B)


      1 #[cfg(not(feature = "std"))]
      2 use alloc::{string::ToString, vec::Vec};
      3 
      4 use radroots_events::{
      5     file_metadata::RadrootsFileMetadata,
      6     kinds::KIND_PUBLIC_FILE_METADATA,
      7     tags::{
      8         TAG_ALT, TAG_BLURHASH, TAG_DIMENSIONS, TAG_FALLBACK, TAG_MAGNET, TAG_MIME,
      9         TAG_ORIGINAL_SHA256, TAG_SERVICE, TAG_SHA256, TAG_SIZE, TAG_SUMMARY, TAG_URL,
     10     },
     11 };
     12 
     13 use crate::error::EventEncodeError;
     14 use crate::field_helpers::{
     15     push_optional_tag, push_tag, validate_lowercase_hex_64, validate_non_empty_field,
     16 };
     17 use crate::social_helpers::{dimensions_tag, push_thumbnail, validate_http_url};
     18 use crate::wire::WireEventParts;
     19 
     20 const DEFAULT_KIND: u32 = KIND_PUBLIC_FILE_METADATA;
     21 
     22 pub fn file_metadata_build_tags(
     23     metadata: &RadrootsFileMetadata,
     24 ) -> Result<Vec<Vec<String>>, EventEncodeError> {
     25     validate_metadata(metadata)?;
     26     let mut tags = Vec::new();
     27     push_tag(&mut tags, TAG_URL, metadata.url.as_str());
     28     push_tag(&mut tags, TAG_MIME, metadata.mime_type.as_str());
     29     push_tag(&mut tags, TAG_SHA256, metadata.sha256.as_str());
     30     push_optional_tag(
     31         &mut tags,
     32         TAG_ORIGINAL_SHA256,
     33         metadata.original_sha256.as_deref(),
     34     );
     35     if let Some(size) = metadata.size {
     36         push_tag(&mut tags, TAG_SIZE, size.to_string());
     37     }
     38     if let Some(dimensions) = metadata.dimensions.as_ref() {
     39         push_tag(&mut tags, TAG_DIMENSIONS, dimensions_tag(dimensions));
     40     }
     41     push_optional_tag(&mut tags, TAG_BLURHASH, metadata.blurhash.as_deref());
     42     if let Some(thumbnails) = metadata.thumbnails.as_ref() {
     43         for thumbnail in thumbnails {
     44             push_thumbnail(&mut tags, thumbnail);
     45         }
     46     }
     47     push_optional_tag(&mut tags, TAG_SUMMARY, metadata.summary.as_deref());
     48     push_optional_tag(&mut tags, TAG_ALT, metadata.alt.as_deref());
     49     push_optional_tag(&mut tags, TAG_FALLBACK, metadata.fallback.as_deref());
     50     push_optional_tag(&mut tags, TAG_MAGNET, metadata.magnet.as_deref());
     51     if let Some(content_hashes) = metadata.content_hashes.as_ref() {
     52         for hash in content_hashes {
     53             push_optional_tag(&mut tags, "i", Some(hash.as_str()));
     54         }
     55     }
     56     if let Some(services) = metadata.services.as_ref() {
     57         for service in services {
     58             push_optional_tag(&mut tags, TAG_SERVICE, Some(service.as_str()));
     59         }
     60     }
     61     Ok(tags)
     62 }
     63 
     64 pub fn to_wire_parts(metadata: &RadrootsFileMetadata) -> Result<WireEventParts, EventEncodeError> {
     65     to_wire_parts_with_kind(metadata, DEFAULT_KIND)
     66 }
     67 
     68 pub fn to_wire_parts_with_kind(
     69     metadata: &RadrootsFileMetadata,
     70     kind: u32,
     71 ) -> Result<WireEventParts, EventEncodeError> {
     72     if kind != DEFAULT_KIND {
     73         return Err(EventEncodeError::InvalidKind(kind));
     74     }
     75     Ok(WireEventParts {
     76         kind,
     77         content: metadata.content.clone().unwrap_or_default(),
     78         tags: file_metadata_build_tags(metadata)?,
     79     })
     80 }
     81 
     82 fn validate_metadata(metadata: &RadrootsFileMetadata) -> Result<(), EventEncodeError> {
     83     validate_http_url(&metadata.url, "url")?;
     84     validate_non_empty_field(&metadata.mime_type, "mime_type")?;
     85     validate_lowercase_hex_64(&metadata.sha256, "sha256")?;
     86     if let Some(hash) = metadata.original_sha256.as_deref() {
     87         validate_lowercase_hex_64(hash, "original_sha256")?;
     88     }
     89     if let Some(dimensions) = metadata.dimensions.as_ref()
     90         && (dimensions.width == 0 || dimensions.height == 0)
     91     {
     92         return Err(EventEncodeError::InvalidField("dimensions"));
     93     }
     94     if let Some(thumbnails) = metadata.thumbnails.as_ref() {
     95         for thumbnail in thumbnails {
     96             validate_http_url(&thumbnail.url, "thumb")?;
     97         }
     98     }
     99     Ok(())
    100 }