social.rs (6042B)
1 use crate::farm::RadrootsFarmRef; 2 3 #[cfg(not(feature = "std"))] 4 use alloc::{string::String, vec::Vec}; 5 6 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 7 #[cfg_attr(feature = "serde", serde(rename_all = "snake_case", tag = "kind"))] 8 #[derive(Clone, Debug, PartialEq, Eq)] 9 pub enum RadrootsSocialTarget { 10 Event { 11 id: String, 12 author: Option<String>, 13 event_kind: Option<u32>, 14 relays: Option<Vec<String>>, 15 }, 16 Address { 17 address: String, 18 author: Option<String>, 19 event_kind: Option<u32>, 20 relays: Option<Vec<String>>, 21 }, 22 External { 23 id: String, 24 external_kind: String, 25 hint: Option<String>, 26 }, 27 } 28 29 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 30 #[derive(Clone, Debug, Default)] 31 pub struct RadrootsSocialFarmAnchor { 32 pub farm: RadrootsFarmRef, 33 pub relays: Option<Vec<String>>, 34 } 35 36 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 37 #[derive(Clone, Debug, Default, PartialEq, Eq)] 38 pub struct RadrootsSocialLocation { 39 pub name: Option<String>, 40 pub geohash: Option<String>, 41 } 42 43 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 44 #[derive(Clone, Debug, Default, PartialEq, Eq)] 45 pub struct RadrootsSocialMediaDimensions { 46 pub width: u32, 47 pub height: u32, 48 } 49 50 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 51 #[derive(Clone, Debug, Default, PartialEq, Eq)] 52 pub struct RadrootsSocialMediaThumbnail { 53 pub url: String, 54 pub dimensions: Option<RadrootsSocialMediaDimensions>, 55 } 56 57 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 58 #[derive(Clone, Debug, Default, PartialEq, Eq)] 59 pub struct RadrootsSocialMediaMetadata { 60 pub url: Option<String>, 61 pub mime_type: Option<String>, 62 pub sha256: Option<String>, 63 pub original_sha256: Option<String>, 64 pub size: Option<u64>, 65 pub dimensions: Option<RadrootsSocialMediaDimensions>, 66 pub blurhash: Option<String>, 67 pub thumbnails: Option<Vec<RadrootsSocialMediaThumbnail>>, 68 pub image: Option<String>, 69 pub summary: Option<String>, 70 pub alt: Option<String>, 71 pub fallback: Option<String>, 72 pub magnet: Option<String>, 73 pub content_hashes: Option<Vec<String>>, 74 pub services: Option<Vec<String>>, 75 pub imeta: Option<Vec<Vec<String>>>, 76 } 77 78 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 79 #[derive(Clone, Debug, Default, PartialEq, Eq)] 80 pub struct RadrootsCalendarParticipant { 81 pub pubkey: String, 82 pub relay: Option<String>, 83 pub role: Option<String>, 84 } 85 86 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 87 #[derive(Clone, Debug, Default, PartialEq, Eq)] 88 pub struct RadrootsCalendarDateValue { 89 pub value: String, 90 } 91 92 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 93 #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] 94 #[derive(Clone, Debug, PartialEq, Eq)] 95 pub enum RadrootsCalendarEventRsvpStatus { 96 Accepted, 97 Declined, 98 Tentative, 99 } 100 101 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 102 #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] 103 #[derive(Clone, Debug, PartialEq, Eq)] 104 pub enum RadrootsCalendarEventFreeBusy { 105 Free, 106 Busy, 107 } 108 109 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 110 #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] 111 #[derive(Clone, Debug, PartialEq, Eq)] 112 pub enum RadrootsReportType { 113 Nudity, 114 Malware, 115 Profanity, 116 Illegal, 117 Spam, 118 Impersonation, 119 Other, 120 } 121 122 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 123 #[derive(Clone, Debug, Default, PartialEq, Eq)] 124 pub struct RadrootsReportFileTarget { 125 pub sha256: Option<String>, 126 pub url: Option<String>, 127 pub magnet: Option<String>, 128 } 129 130 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] 131 #[derive(Clone, Debug, PartialEq, Eq)] 132 pub struct RadrootsReportTarget { 133 pub reported_pubkey: String, 134 pub event: Option<RadrootsSocialTarget>, 135 pub file: Option<RadrootsReportFileTarget>, 136 } 137 138 #[cfg(test)] 139 mod tests { 140 use super::*; 141 142 #[test] 143 fn supports_nip22_target_shapes() { 144 let event = RadrootsSocialTarget::Event { 145 id: "a".repeat(64), 146 author: Some("b".repeat(64)), 147 event_kind: Some(30023), 148 relays: Some(vec!["wss://relay.example".to_string()]), 149 }; 150 let address = RadrootsSocialTarget::Address { 151 address: "30023:pubkey:d-tag".to_string(), 152 author: None, 153 event_kind: Some(30023), 154 relays: None, 155 }; 156 let external = RadrootsSocialTarget::External { 157 id: "https://example.test/object".to_string(), 158 external_kind: "web".to_string(), 159 hint: None, 160 }; 161 162 assert!(matches!(event, RadrootsSocialTarget::Event { .. })); 163 assert!(matches!(address, RadrootsSocialTarget::Address { .. })); 164 assert!(matches!(external, RadrootsSocialTarget::External { .. })); 165 } 166 167 #[test] 168 fn defaults_media_and_farm_anchor_primitives() { 169 let media = RadrootsSocialMediaMetadata::default(); 170 assert!(media.url.is_none()); 171 assert!(media.content_hashes.is_none()); 172 assert!(media.services.is_none()); 173 174 let anchor = RadrootsSocialFarmAnchor::default(); 175 assert!(anchor.farm.pubkey.is_empty()); 176 assert!(anchor.farm.d_tag.is_empty()); 177 assert!(anchor.relays.is_none()); 178 } 179 180 #[test] 181 fn exposes_calendar_and_report_enums() { 182 assert_eq!( 183 RadrootsCalendarEventRsvpStatus::Accepted, 184 RadrootsCalendarEventRsvpStatus::Accepted 185 ); 186 assert_eq!( 187 RadrootsCalendarEventFreeBusy::Busy, 188 RadrootsCalendarEventFreeBusy::Busy 189 ); 190 assert_eq!(RadrootsReportType::Spam, RadrootsReportType::Spam); 191 } 192 }