lib

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

file_metadata.rs (3556B)


      1 #[cfg(not(feature = "std"))]
      2 use alloc::{string::String, vec::Vec};
      3 
      4 use crate::social::{SocialMediaDimensions, SocialMediaThumbnail};
      5 
      6 #[cfg_attr(
      7     any(feature = "serde", test),
      8     derive(serde::Serialize, serde::Deserialize)
      9 )]
     10 #[derive(Clone, Debug)]
     11 pub struct FileMetadata {
     12     pub url: String,
     13     pub mime_type: String,
     14     pub sha256: String,
     15     #[cfg_attr(
     16         feature = "serde",
     17         serde(default, skip_serializing_if = "Option::is_none")
     18     )]
     19     pub original_sha256: Option<String>,
     20     #[cfg_attr(
     21         feature = "serde",
     22         serde(default, skip_serializing_if = "Option::is_none")
     23     )]
     24     pub size: Option<u64>,
     25     #[cfg_attr(
     26         feature = "serde",
     27         serde(default, skip_serializing_if = "Option::is_none")
     28     )]
     29     pub dimensions: Option<SocialMediaDimensions>,
     30     #[cfg_attr(
     31         feature = "serde",
     32         serde(default, skip_serializing_if = "Option::is_none")
     33     )]
     34     pub blurhash: Option<String>,
     35     #[cfg_attr(
     36         feature = "serde",
     37         serde(default, skip_serializing_if = "Option::is_none")
     38     )]
     39     pub thumbnails: Option<Vec<SocialMediaThumbnail>>,
     40     #[cfg_attr(
     41         feature = "serde",
     42         serde(default, skip_serializing_if = "Option::is_none")
     43     )]
     44     pub summary: Option<String>,
     45     #[cfg_attr(
     46         feature = "serde",
     47         serde(default, skip_serializing_if = "Option::is_none")
     48     )]
     49     pub alt: Option<String>,
     50     #[cfg_attr(
     51         feature = "serde",
     52         serde(default, skip_serializing_if = "Option::is_none")
     53     )]
     54     pub fallback: Option<String>,
     55     #[cfg_attr(
     56         feature = "serde",
     57         serde(default, skip_serializing_if = "Option::is_none")
     58     )]
     59     pub magnet: Option<String>,
     60     #[cfg_attr(
     61         feature = "serde",
     62         serde(default, skip_serializing_if = "Option::is_none")
     63     )]
     64     pub content_hashes: Option<Vec<String>>,
     65     #[cfg_attr(
     66         feature = "serde",
     67         serde(default, skip_serializing_if = "Option::is_none")
     68     )]
     69     pub services: Option<Vec<String>>,
     70     #[cfg_attr(
     71         feature = "serde",
     72         serde(default, skip_serializing_if = "Option::is_none")
     73     )]
     74     pub content: Option<String>,
     75 }
     76 
     77 #[cfg(all(test, feature = "std", feature = "serde"))]
     78 #[cfg_attr(coverage_nightly, coverage(off))]
     79 mod tests {
     80     use super::*;
     81 
     82     #[test]
     83     fn file_metadata_represents_required_nip94_fields() {
     84         let metadata = FileMetadata {
     85             url: "https://example.test/file.jpg".to_string(),
     86             mime_type: "image/jpeg".to_string(),
     87             sha256: "a".repeat(64),
     88             original_sha256: Some("b".repeat(64)),
     89             size: Some(1024),
     90             dimensions: Some(SocialMediaDimensions {
     91                 width: 640,
     92                 height: 480,
     93             }),
     94             blurhash: None,
     95             thumbnails: None,
     96             summary: Some("field image".to_string()),
     97             alt: Some("rows of lettuce".to_string()),
     98             fallback: None,
     99             magnet: Some("magnet:?xt=urn:btih:abc".to_string()),
    100             content_hashes: Some(vec!["sha256:a".to_string()]),
    101             services: Some(vec!["https://media.example.test".to_string()]),
    102             content: Some("caption".to_string()),
    103         };
    104 
    105         assert_eq!(metadata.mime_type, "image/jpeg");
    106         assert_eq!(metadata.sha256.len(), 64);
    107         assert_eq!(metadata.dimensions.expect("dimensions").width, 640);
    108         assert!(metadata.magnet.expect("magnet").starts_with("magnet:"));
    109         assert_eq!(metadata.services.expect("services").len(), 1);
    110     }
    111 }