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