admission.rs (4146B)
1 use core::fmt; 2 3 use radroots_event::{contract::EventContract, envelope::EventEnvelope}; 4 5 use crate::{ 6 comment::inbound::{ 7 RadrootsInboundNip22CommentProjection, RadrootsNip22CommentProjectionError, 8 project_verified_nip22_comment_event, 9 }, 10 verification::{ 11 RadrootsNip01VerificationError, RadrootsSignatureVerifiedEvent, verify_nip01_event, 12 }, 13 }; 14 15 /// A signature-and-id verified kind-1111 event admitted as a NIP-22 Comment. 16 #[derive(Clone, Debug, PartialEq, Eq)] 17 pub struct RadrootsAdmittedNip22CommentEvent { 18 verified_event: RadrootsSignatureVerifiedEvent, 19 projection: RadrootsInboundNip22CommentProjection, 20 } 21 22 impl RadrootsAdmittedNip22CommentEvent { 23 pub fn verified_event(&self) -> &RadrootsSignatureVerifiedEvent { 24 &self.verified_event 25 } 26 27 pub fn event(&self) -> &EventEnvelope { 28 self.verified_event.event() 29 } 30 31 pub const fn projection(&self) -> &RadrootsInboundNip22CommentProjection { 32 &self.projection 33 } 34 35 pub fn contract(&self) -> &'static EventContract { 36 radroots_event::contract::event_contract(self.projection.contract_id()) 37 .expect("NIP-22 Comment contract is registry-owned") 38 } 39 40 pub fn into_parts( 41 self, 42 ) -> ( 43 RadrootsSignatureVerifiedEvent, 44 RadrootsInboundNip22CommentProjection, 45 ) { 46 (self.verified_event, self.projection) 47 } 48 } 49 50 #[non_exhaustive] 51 #[derive(Clone, Debug, PartialEq, Eq)] 52 pub enum RadrootsNip22CommentAdmissionError { 53 Nip01Verification(RadrootsNip01VerificationError), 54 Projection(RadrootsNip22CommentProjectionError), 55 } 56 57 impl RadrootsNip22CommentAdmissionError { 58 pub const fn code(&self) -> &'static str { 59 match self { 60 Self::Nip01Verification(error) => error.code(), 61 Self::Projection(error) => error.code(), 62 } 63 } 64 } 65 66 impl fmt::Display for RadrootsNip22CommentAdmissionError { 67 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 68 match self { 69 Self::Nip01Verification(error) => write!(formatter, "{error}"), 70 Self::Projection(error) => write!(formatter, "{error}"), 71 } 72 } 73 } 74 75 #[cfg(feature = "std")] 76 impl std::error::Error for RadrootsNip22CommentAdmissionError { 77 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { 78 match self { 79 Self::Nip01Verification(error) => Some(error), 80 Self::Projection(error) => Some(error), 81 } 82 } 83 } 84 85 impl From<RadrootsNip01VerificationError> for RadrootsNip22CommentAdmissionError { 86 fn from(value: RadrootsNip01VerificationError) -> Self { 87 Self::Nip01Verification(value) 88 } 89 } 90 91 impl From<RadrootsNip22CommentProjectionError> for RadrootsNip22CommentAdmissionError { 92 fn from(value: RadrootsNip22CommentProjectionError) -> Self { 93 Self::Projection(value) 94 } 95 } 96 97 pub fn admit_verified_nip22_comment_event( 98 verified_event: RadrootsSignatureVerifiedEvent, 99 ) -> Result<RadrootsAdmittedNip22CommentEvent, RadrootsNip22CommentAdmissionError> { 100 let projection = project_verified_nip22_comment_event(&verified_event)?; 101 Ok(RadrootsAdmittedNip22CommentEvent { 102 verified_event, 103 projection, 104 }) 105 } 106 107 pub fn verify_and_admit_nip22_comment_event( 108 event: EventEnvelope, 109 ) -> Result<RadrootsAdmittedNip22CommentEvent, RadrootsNip22CommentAdmissionError> { 110 admit_verified_nip22_comment_event(verify_nip01_event(event)?) 111 } 112 113 #[cfg(test)] 114 mod tests { 115 use super::*; 116 117 #[test] 118 fn stable_error_codes_delegate_to_verification_and_projection() { 119 let verification = RadrootsNip22CommentAdmissionError::Nip01Verification( 120 RadrootsNip01VerificationError::SignatureInvalid, 121 ); 122 let projection = RadrootsNip22CommentAdmissionError::Projection( 123 RadrootsNip22CommentProjectionError::ParentAuthorAmbiguous, 124 ); 125 assert_eq!(verification.code(), "signature_invalid"); 126 assert_eq!(projection.code(), "comment_parent_author_ambiguous"); 127 assert!(!verification.to_string().is_empty()); 128 assert!(!projection.to_string().is_empty()); 129 } 130 }