lib

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

farm_workspace.rs (5376B)


      1 #![forbid(unsafe_code)]
      2 
      3 use crate::envelope::kind::KIND_FARM_WORKSPACE_MANIFEST as KIND_FARM_WORKSPACE_MANIFEST_EVENT;
      4 use crate::farm::FarmRef;
      5 
      6 #[cfg(not(feature = "std"))]
      7 use alloc::{string::String, vec::Vec};
      8 
      9 pub const KIND_FARM_WORKSPACE_MANIFEST: u32 = KIND_FARM_WORKSPACE_MANIFEST_EVENT;
     10 pub const RADROOTS_FARM_WORKSPACE_SCHEMA: &str = "radroots.farm.workspace.v1";
     11 pub const RADROOTS_FARM_WORKSPACE_PROTOCOL_VERSION: &str = "field-nostr-v1";
     12 pub const RADROOTS_FARM_WORKSPACE_TAG: &str = "radroots:farm:workspace";
     13 
     14 #[cfg_attr(
     15     any(feature = "serde", test),
     16     derive(serde::Serialize, serde::Deserialize)
     17 )]
     18 #[derive(Clone, Debug)]
     19 pub struct FarmWorkspaceManifest {
     20     pub d_tag: String,
     21     pub schema: String,
     22     pub farm_group_id: String,
     23     pub name: String,
     24     pub owner_pubkey: String,
     25     pub farm: Option<FarmRef>,
     26     pub relays: Vec<FarmWorkspaceRelay>,
     27     pub media_servers: Vec<FarmWorkspaceMediaServer>,
     28     pub supported_kinds: Vec<u32>,
     29     pub protocol_version: String,
     30     pub created_at_ms: u64,
     31     pub updated_at_ms: Option<u64>,
     32 }
     33 
     34 #[cfg_attr(
     35     any(feature = "serde", test),
     36     derive(serde::Serialize, serde::Deserialize)
     37 )]
     38 #[derive(Clone, Debug, Default, PartialEq, Eq)]
     39 pub struct FarmWorkspaceRef {
     40     pub pubkey: String,
     41     pub d_tag: String,
     42 }
     43 
     44 #[cfg_attr(
     45     any(feature = "serde", test),
     46     derive(serde::Serialize, serde::Deserialize)
     47 )]
     48 #[derive(Clone, Debug, PartialEq, Eq)]
     49 pub struct FarmWorkspaceRelay {
     50     pub url: String,
     51     pub mode: FarmWorkspaceRelayMode,
     52 }
     53 
     54 #[cfg_attr(
     55     any(feature = "serde", test),
     56     derive(serde::Serialize, serde::Deserialize)
     57 )]
     58 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
     59 pub enum FarmWorkspaceRelayMode {
     60     Read,
     61     Write,
     62     ReadWrite,
     63 }
     64 
     65 #[cfg_attr(
     66     any(feature = "serde", test),
     67     derive(serde::Serialize, serde::Deserialize)
     68 )]
     69 #[derive(Clone, Debug, PartialEq, Eq)]
     70 pub struct FarmWorkspaceMediaServer {
     71     pub url: String,
     72     pub service: String,
     73 }
     74 
     75 #[cfg(all(test, feature = "serde"))]
     76 #[cfg_attr(coverage_nightly, coverage(off))]
     77 mod tests {
     78     use super::*;
     79     use crate::envelope::kind::{
     80         KIND_APP_DATA, KIND_FARM_CRDT_CHANGE, KIND_FARM_FILE_METADATA,
     81         KIND_FARM_WORKSPACE_MANIFEST as KIND_FARM_WORKSPACE_MANIFEST_KIND, KIND_HTTP_AUTH,
     82         KIND_RELAY_AUTH,
     83     };
     84 
     85     #[test]
     86     fn manifest_kind_aliases_existing_app_data_kind() {
     87         assert_eq!(KIND_FARM_WORKSPACE_MANIFEST, KIND_APP_DATA);
     88         assert_eq!(KIND_FARM_WORKSPACE_MANIFEST_KIND, KIND_APP_DATA);
     89     }
     90 
     91     #[test]
     92     fn manifest_represents_required_workspace_contract_fields() {
     93         let manifest = sample_manifest();
     94 
     95         assert_eq!(manifest.d_tag, "ABCDEFGHIJKLMNOPQRSTUV");
     96         assert_eq!(manifest.schema, RADROOTS_FARM_WORKSPACE_SCHEMA);
     97         assert_eq!(manifest.farm_group_id, "BCDEFGHIJKLMNOPQRSTUVW");
     98         assert_eq!(manifest.relays.len(), 1);
     99         assert_eq!(manifest.media_servers.len(), 1);
    100         assert!(manifest.supported_kinds.contains(&KIND_FARM_CRDT_CHANGE));
    101         assert!(
    102             manifest
    103                 .supported_kinds
    104                 .contains(&KIND_FARM_WORKSPACE_MANIFEST)
    105         );
    106         assert_eq!(manifest.created_at_ms, 1_780_000_000_000);
    107         assert_eq!(manifest.updated_at_ms, None);
    108     }
    109 
    110     #[test]
    111     fn manifest_serializes_stable_content_shape() {
    112         let value = serde_json::to_value(sample_manifest()).unwrap();
    113 
    114         assert_eq!(value["schema"], RADROOTS_FARM_WORKSPACE_SCHEMA);
    115         assert_eq!(
    116             value["protocol_version"],
    117             RADROOTS_FARM_WORKSPACE_PROTOCOL_VERSION
    118         );
    119         assert_eq!(value["farm"]["d_tag"], "CDEFGHIJKLMNOPQRSTUVWX");
    120         assert_eq!(value["relays"][0]["mode"], "ReadWrite");
    121         assert_eq!(value["media_servers"][0]["service"], "RadrootsPrivateMedia");
    122         assert_eq!(value["supported_kinds"][0], KIND_FARM_CRDT_CHANGE);
    123         assert_eq!(value["supported_kinds"][1], KIND_FARM_WORKSPACE_MANIFEST);
    124     }
    125 
    126     fn sample_manifest() -> FarmWorkspaceManifest {
    127         FarmWorkspaceManifest {
    128             d_tag: "ABCDEFGHIJKLMNOPQRSTUV".to_string(),
    129             schema: RADROOTS_FARM_WORKSPACE_SCHEMA.to_string(),
    130             farm_group_id: "BCDEFGHIJKLMNOPQRSTUVW".to_string(),
    131             name: "Small Regen Farm".to_string(),
    132             owner_pubkey: "owner_pubkey".to_string(),
    133             farm: Some(FarmRef {
    134                 pubkey: "farm_pubkey".to_string(),
    135                 d_tag: "CDEFGHIJKLMNOPQRSTUVWX".to_string(),
    136             }),
    137             relays: vec![FarmWorkspaceRelay {
    138                 url: "wss://relay.example.invalid/farm/ABCDEFGHIJKLMNOPQRSTUV".to_string(),
    139                 mode: FarmWorkspaceRelayMode::ReadWrite,
    140             }],
    141             media_servers: vec![FarmWorkspaceMediaServer {
    142                 url: "https://media.example.invalid/farm/ABCDEFGHIJKLMNOPQRSTUV".to_string(),
    143                 service: "RadrootsPrivateMedia".to_string(),
    144             }],
    145             supported_kinds: vec![
    146                 KIND_FARM_CRDT_CHANGE,
    147                 KIND_FARM_WORKSPACE_MANIFEST,
    148                 KIND_FARM_FILE_METADATA,
    149                 KIND_RELAY_AUTH,
    150                 KIND_HTTP_AUTH,
    151             ],
    152             protocol_version: RADROOTS_FARM_WORKSPACE_PROTOCOL_VERSION.to_string(),
    153             created_at_ms: 1_780_000_000_000,
    154             updated_at_ms: None,
    155         }
    156     }
    157 }