food_availability.rs (2654B)
1 //! Sealed authoring for focused Radroots FoodAvailability events. 2 3 use crate::{ 4 error::Error, 5 events::sealed::SealedBuilderCore, 6 types::{ 7 ExternalSigningRequest, RadrootsNostrEvent, RadrootsNostrKeys, RadrootsNostrPublicKey, 8 RadrootsNostrTimestamp, 9 }, 10 }; 11 use radroots_event::food::availability::FoodAvailabilityDetails; 12 use radroots_event_codec::authoring::{AuthoredEventBody, AuthoredPlanError}; 13 14 /// A sealed builder for a validated focused FoodAvailability event. 15 /// 16 /// The timestamp is fixed during typed construction because it participates in 17 /// strict domain validation and the canonical compact-wire budget. 18 /// Byte-verified image descriptors are not upload evidence. A media-bearing 19 /// caller must prove successful BUD-02 upload before signing or publication. 20 /// 21 /// ```compile_fail 22 /// use radroots_nostr::event::{FoodAvailabilityBuilder, Timestamp}; 23 /// 24 /// fn replace_validated_timestamp(builder: FoodAvailabilityBuilder) { 25 /// let _ = builder.custom_created_at(Timestamp::from_secs(1)); 26 /// } 27 /// ``` 28 /// 29 /// ```compile_fail 30 /// use radroots_nostr::event::FoodAvailabilityBuilder; 31 /// 32 /// fn expose_raw_builder(builder: FoodAvailabilityBuilder) { 33 /// let _: nostr::EventBuilder = builder.into(); 34 /// } 35 /// ``` 36 #[must_use = "FoodAvailability event builders must be signed or published"] 37 pub struct FoodAvailabilityBuilder { 38 inner: SealedBuilderCore, 39 } 40 41 impl FoodAvailabilityBuilder { 42 /// Signs the validated event directly with local keys. 43 /// 44 /// Media-bearing callers must prove successful BUD-02 upload first. 45 pub fn sign_with_keys(self, keys: &RadrootsNostrKeys) -> Result<RadrootsNostrEvent, Error> { 46 self.inner.sign_with_keys(keys) 47 } 48 49 pub fn into_external_signing_request( 50 self, 51 public_key: RadrootsNostrPublicKey, 52 ) -> Result<ExternalSigningRequest, Error> { 53 self.inner.into_external_signing_request(public_key) 54 } 55 } 56 57 /// Builds a sealed Nostr builder from strict FoodAvailability details. 58 /// 59 /// This validates media descriptors but does not attest BUD-02 upload. 60 pub fn build_food_availability_event( 61 details: &FoodAvailabilityDetails, 62 created_at: RadrootsNostrTimestamp, 63 ) -> Result<FoodAvailabilityBuilder, Error> { 64 let body = AuthoredEventBody::from_food_availability(details, created_at.as_secs()).map_err( 65 |error| match error { 66 AuthoredPlanError::FoodAvailability(error) => Error::FoodAvailabilityEncode(error), 67 error => Error::AuthoredPlan(error), 68 }, 69 )?; 70 let inner = SealedBuilderCore::at(body, created_at); 71 Ok(FoodAvailabilityBuilder { inner }) 72 }