errors.rs (4592B)
1 use core::fmt; 2 3 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 4 pub enum GroupReplyPrefix { 5 Duplicate, 6 Blocked, 7 RateLimited, 8 Invalid, 9 Restricted, 10 AuthRequired, 11 Error, 12 } 13 14 impl GroupReplyPrefix { 15 pub fn as_str(self) -> &'static str { 16 match self { 17 Self::Duplicate => "duplicate", 18 Self::Blocked => "blocked", 19 Self::RateLimited => "rate-limited", 20 Self::Invalid => "invalid", 21 Self::Restricted => "restricted", 22 Self::AuthRequired => "auth-required", 23 Self::Error => "error", 24 } 25 } 26 } 27 28 impl fmt::Display for GroupReplyPrefix { 29 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 30 formatter.write_str(self.as_str()) 31 } 32 } 33 34 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 35 pub enum GroupErrorKind { 36 InvalidGroupId, 37 MalformedGroupTag, 38 MissingGroupTag, 39 ConflictingGroupTag, 40 TooManyGroupTags, 41 UnsupportedGroupKind, 42 DirectRelayGeneratedSubmission, 43 MissingTargetTag, 44 MalformedTargetTag, 45 MetadataTooLarge, 46 TooManySupportedKinds, 47 InvalidRole, 48 MissingCapability, 49 AuthenticationRequired, 50 GroupUnavailable, 51 GroupDeleted, 52 GroupAlreadyExists, 53 DuplicateMember, 54 Internal, 55 } 56 57 #[derive(Debug, Clone, PartialEq, Eq)] 58 pub struct GroupError { 59 kind: GroupErrorKind, 60 prefix: GroupReplyPrefix, 61 message: String, 62 } 63 64 impl GroupError { 65 pub fn new(kind: GroupErrorKind, prefix: GroupReplyPrefix, message: impl Into<String>) -> Self { 66 Self { 67 kind, 68 prefix, 69 message: message.into(), 70 } 71 } 72 73 pub fn invalid(kind: GroupErrorKind, message: impl Into<String>) -> Self { 74 Self::new(kind, GroupReplyPrefix::Invalid, message) 75 } 76 77 pub fn duplicate(kind: GroupErrorKind, message: impl Into<String>) -> Self { 78 Self::new(kind, GroupReplyPrefix::Duplicate, message) 79 } 80 81 pub fn blocked(kind: GroupErrorKind, message: impl Into<String>) -> Self { 82 Self::new(kind, GroupReplyPrefix::Blocked, message) 83 } 84 85 pub fn restricted(kind: GroupErrorKind, message: impl Into<String>) -> Self { 86 Self::new(kind, GroupReplyPrefix::Restricted, message) 87 } 88 89 pub fn auth_required(message: impl Into<String>) -> Self { 90 Self::new( 91 GroupErrorKind::AuthenticationRequired, 92 GroupReplyPrefix::AuthRequired, 93 message, 94 ) 95 } 96 97 pub fn internal(message: impl Into<String>) -> Self { 98 Self::new(GroupErrorKind::Internal, GroupReplyPrefix::Error, message) 99 } 100 101 pub fn kind(&self) -> GroupErrorKind { 102 self.kind 103 } 104 105 pub fn reply_prefix(&self) -> GroupReplyPrefix { 106 self.prefix 107 } 108 109 pub fn message(&self) -> &str { 110 &self.message 111 } 112 113 pub fn prefixed_message(&self) -> String { 114 format!("{}: {}", self.prefix.as_str(), self.message) 115 } 116 } 117 118 impl fmt::Display for GroupError { 119 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 120 formatter.write_str(&self.prefixed_message()) 121 } 122 } 123 124 impl std::error::Error for GroupError {} 125 126 #[cfg(test)] 127 mod tests { 128 use super::{GroupError, GroupErrorKind, GroupReplyPrefix}; 129 130 #[test] 131 fn group_errors_map_to_nostr_reply_prefixes() { 132 let cases = [ 133 (GroupReplyPrefix::Duplicate, "duplicate"), 134 (GroupReplyPrefix::Blocked, "blocked"), 135 (GroupReplyPrefix::RateLimited, "rate-limited"), 136 (GroupReplyPrefix::Invalid, "invalid"), 137 (GroupReplyPrefix::Restricted, "restricted"), 138 (GroupReplyPrefix::AuthRequired, "auth-required"), 139 (GroupReplyPrefix::Error, "error"), 140 ]; 141 142 for (prefix, value) in cases { 143 assert_eq!(prefix.as_str(), value); 144 assert_eq!(prefix.to_string(), value); 145 } 146 147 let error = GroupError::restricted( 148 GroupErrorKind::MissingCapability, 149 "missing group capability manage_members", 150 ); 151 152 assert_eq!(error.reply_prefix(), GroupReplyPrefix::Restricted); 153 assert_eq!( 154 error.prefixed_message(), 155 "restricted: missing group capability manage_members" 156 ); 157 158 let duplicate = GroupError::duplicate( 159 GroupErrorKind::DuplicateMember, 160 "group member already exists", 161 ); 162 163 assert_eq!(duplicate.reply_prefix(), GroupReplyPrefix::Duplicate); 164 assert_eq!( 165 duplicate.prefixed_message(), 166 "duplicate: group member already exists" 167 ); 168 } 169 }