lib

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

farm_file.rs (4850B)


      1 #![forbid(unsafe_code)]
      2 
      3 use crate::envelope::kind::KIND_FARM_FILE_METADATA as KIND_FARM_FILE_METADATA_EVENT;
      4 use crate::farm::crdt::FarmCrdtDocumentKind;
      5 use crate::farm::workspace::FarmWorkspaceRef;
      6 
      7 #[cfg(not(feature = "std"))]
      8 use alloc::{string::String, vec::Vec};
      9 
     10 pub const KIND_FARM_FILE_METADATA: u32 = KIND_FARM_FILE_METADATA_EVENT;
     11 
     12 #[cfg_attr(
     13     any(feature = "serde", test),
     14     derive(serde::Serialize, serde::Deserialize)
     15 )]
     16 #[derive(Clone, Debug, PartialEq, Eq)]
     17 pub struct FarmFileMetadata {
     18     pub d_tag: String,
     19     pub workspace: FarmWorkspaceRef,
     20     pub farm_group_id: String,
     21     pub owner_document_id: String,
     22     pub owner_document_kind: FarmCrdtDocumentKind,
     23     pub caption: Option<String>,
     24     pub url: String,
     25     pub mime_type: String,
     26     pub sha256: String,
     27     pub original_sha256: Option<String>,
     28     pub size_bytes: Option<u64>,
     29     pub dimensions: Option<FarmFileDimensions>,
     30     pub blurhash: Option<String>,
     31     pub thumb: Option<FarmFileSource>,
     32     pub image: Option<FarmFileSource>,
     33     pub alt: Option<String>,
     34     pub fallbacks: Vec<String>,
     35 }
     36 
     37 #[cfg_attr(
     38     any(feature = "serde", test),
     39     derive(serde::Serialize, serde::Deserialize)
     40 )]
     41 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
     42 pub struct FarmFileDimensions {
     43     pub w: u32,
     44     pub h: u32,
     45 }
     46 
     47 #[cfg_attr(
     48     any(feature = "serde", test),
     49     derive(serde::Serialize, serde::Deserialize)
     50 )]
     51 #[derive(Clone, Debug, PartialEq, Eq)]
     52 pub struct FarmFileSource {
     53     pub url: String,
     54     pub mime_type: Option<String>,
     55     pub dimensions: Option<FarmFileDimensions>,
     56 }
     57 
     58 #[cfg(all(test, feature = "serde"))]
     59 #[cfg_attr(coverage_nightly, coverage(off))]
     60 mod tests {
     61     use super::*;
     62 
     63     #[test]
     64     fn file_metadata_kind_uses_nip94_file_metadata_kind() {
     65         assert_eq!(KIND_FARM_FILE_METADATA, 1063);
     66     }
     67 
     68     #[test]
     69     fn file_metadata_remains_separate_from_message_file_model() {
     70         let metadata = sample_file_metadata();
     71 
     72         assert_eq!(metadata.d_tag, "EFGHIJKLMNOPQRSTUVWXYZ");
     73         assert_eq!(metadata.owner_document_id, "DEFGHIJKLMNOPQRSTUVWXY");
     74         assert_eq!(metadata.owner_document_kind, FarmCrdtDocumentKind::FarmTask);
     75         assert_eq!(
     76             metadata.caption.as_deref(),
     77             Some("Tomatoes harvested from Patch Y.")
     78         );
     79         assert_eq!(metadata.mime_type, "image/jpeg");
     80         assert_eq!(
     81             metadata.dimensions,
     82             Some(FarmFileDimensions { w: 1600, h: 1200 })
     83         );
     84         assert_eq!(metadata.fallbacks.len(), 1);
     85     }
     86 
     87     #[test]
     88     fn file_metadata_serializes_stable_content_shape() {
     89         let value = serde_json::to_value(sample_file_metadata()).unwrap();
     90 
     91         assert_eq!(value["workspace"]["d_tag"], "ABCDEFGHIJKLMNOPQRSTUV");
     92         assert_eq!(value["farm_group_id"], "BCDEFGHIJKLMNOPQRSTUVW");
     93         assert_eq!(value["owner_document_kind"], "FarmTask");
     94         assert_eq!(value["caption"], "Tomatoes harvested from Patch Y.");
     95         assert_eq!(value["mime_type"], "image/jpeg");
     96         assert_eq!(
     97             value["sha256"],
     98             "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
     99         );
    100         assert_eq!(value["dimensions"]["w"], 1600);
    101         assert_eq!(value["dimensions"]["h"], 1200);
    102     }
    103 
    104     fn sample_file_metadata() -> FarmFileMetadata {
    105         FarmFileMetadata {
    106             d_tag: "EFGHIJKLMNOPQRSTUVWXYZ".to_string(),
    107             workspace: FarmWorkspaceRef {
    108                 pubkey: "workspace_pubkey".to_string(),
    109                 d_tag: "ABCDEFGHIJKLMNOPQRSTUV".to_string(),
    110             },
    111             farm_group_id: "BCDEFGHIJKLMNOPQRSTUVW".to_string(),
    112             owner_document_id: "DEFGHIJKLMNOPQRSTUVWXY".to_string(),
    113             owner_document_kind: FarmCrdtDocumentKind::FarmTask,
    114             caption: Some("Tomatoes harvested from Patch Y.".to_string()),
    115             url: "https://media.example.invalid/blob/sha256".to_string(),
    116             mime_type: "image/jpeg".to_string(),
    117             sha256: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef".to_string(),
    118             original_sha256: Some(
    119                 "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789".to_string(),
    120             ),
    121             size_bytes: Some(123_456),
    122             dimensions: Some(FarmFileDimensions { w: 1600, h: 1200 }),
    123             blurhash: Some("LEHV6nWB2yk8pyo0adR*.7kCMdnj".to_string()),
    124             thumb: Some(FarmFileSource {
    125                 url: "https://media.example.invalid/thumb/sha256".to_string(),
    126                 mime_type: Some("image/jpeg".to_string()),
    127                 dimensions: Some(FarmFileDimensions { w: 320, h: 240 }),
    128             }),
    129             image: None,
    130             alt: Some("Harvested tomatoes in a crate".to_string()),
    131             fallbacks: vec!["https://fallback.example.invalid/blob/sha256".to_string()],
    132         }
    133     }
    134 }