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