encode.rs (3601B)
1 #[cfg(not(feature = "std"))] 2 use alloc::{ 3 string::{String, ToString}, 4 vec::Vec, 5 }; 6 7 use radroots_events::{ 8 farm_workspace::{ 9 KIND_FARM_WORKSPACE_MANIFEST, RADROOTS_FARM_WORKSPACE_SCHEMA, RADROOTS_FARM_WORKSPACE_TAG, 10 RadrootsFarmWorkspaceManifest, 11 }, 12 kinds::{KIND_FARM, KIND_FARM_CRDT_CHANGE, KIND_FARM_FILE_METADATA}, 13 tags::{TAG_A, TAG_D, TAG_H, TAG_P, TAG_T}, 14 }; 15 16 use crate::d_tag::validate_d_tag; 17 use crate::error::EventEncodeError; 18 use crate::field_helpers::{address_string, push_tag, validate_non_empty_field}; 19 #[cfg(feature = "serde_json")] 20 use crate::wire::WireEventParts; 21 22 pub fn farm_workspace_build_tags( 23 manifest: &RadrootsFarmWorkspaceManifest, 24 ) -> Result<Vec<Vec<String>>, EventEncodeError> { 25 validate_manifest(manifest)?; 26 let mut tags = Vec::new(); 27 push_tag(&mut tags, TAG_D, manifest.d_tag.as_str()); 28 push_tag(&mut tags, TAG_H, manifest.farm_group_id.as_str()); 29 push_tag(&mut tags, TAG_P, manifest.owner_pubkey.as_str()); 30 push_tag(&mut tags, TAG_T, RADROOTS_FARM_WORKSPACE_TAG); 31 if let Some(farm) = manifest.farm.as_ref() { 32 let address = address_string(KIND_FARM, &farm.pubkey, &farm.d_tag, "farm")?; 33 push_tag(&mut tags, TAG_A, address); 34 } 35 Ok(tags) 36 } 37 38 #[cfg(feature = "serde_json")] 39 pub fn to_wire_parts( 40 manifest: &RadrootsFarmWorkspaceManifest, 41 ) -> Result<WireEventParts, EventEncodeError> { 42 to_wire_parts_with_kind(manifest, KIND_FARM_WORKSPACE_MANIFEST) 43 } 44 45 #[cfg(feature = "serde_json")] 46 pub fn to_wire_parts_with_kind( 47 manifest: &RadrootsFarmWorkspaceManifest, 48 kind: u32, 49 ) -> Result<WireEventParts, EventEncodeError> { 50 if kind != KIND_FARM_WORKSPACE_MANIFEST { 51 return Err(EventEncodeError::InvalidKind(kind)); 52 } 53 let tags = farm_workspace_build_tags(manifest)?; 54 let content = serde_json::to_string(manifest).map_err(|_| EventEncodeError::Json)?; 55 Ok(WireEventParts { 56 kind, 57 content, 58 tags, 59 }) 60 } 61 62 pub(crate) fn validate_manifest( 63 manifest: &RadrootsFarmWorkspaceManifest, 64 ) -> Result<(), EventEncodeError> { 65 validate_d_tag(&manifest.d_tag, "d_tag")?; 66 validate_non_empty_field(&manifest.farm_group_id, "farm_group_id")?; 67 validate_non_empty_field(&manifest.name, "name")?; 68 validate_non_empty_field(&manifest.owner_pubkey, "owner_pubkey")?; 69 validate_non_empty_field(&manifest.protocol_version, "protocol_version")?; 70 if manifest.schema != RADROOTS_FARM_WORKSPACE_SCHEMA { 71 return Err(EventEncodeError::InvalidField("schema")); 72 } 73 if manifest.relays.is_empty() { 74 return Err(EventEncodeError::EmptyRequiredField("relays")); 75 } 76 if !manifest 77 .supported_kinds 78 .contains(&KIND_FARM_WORKSPACE_MANIFEST) 79 || !manifest.supported_kinds.contains(&KIND_FARM_CRDT_CHANGE) 80 { 81 return Err(EventEncodeError::InvalidField("supported_kinds")); 82 } 83 if !manifest.media_servers.is_empty() 84 && !manifest.supported_kinds.contains(&KIND_FARM_FILE_METADATA) 85 { 86 return Err(EventEncodeError::InvalidField("supported_kinds")); 87 } 88 for relay in &manifest.relays { 89 validate_non_empty_field(&relay.url, "relays.url")?; 90 } 91 for media_server in &manifest.media_servers { 92 validate_non_empty_field(&media_server.url, "media_servers.url")?; 93 validate_non_empty_field(&media_server.service, "media_servers.service")?; 94 } 95 if let Some(farm) = manifest.farm.as_ref() { 96 validate_non_empty_field(&farm.pubkey, "farm.pubkey")?; 97 validate_d_tag(&farm.d_tag, "farm.d_tag")?; 98 } 99 Ok(()) 100 }