@@ -134,9 +134,12 @@ pub struct ExplicitMetadata {}
134134pub struct DerivedMetadata { }
135135
136136impl MetadataStrategy for ExplicitMetadata { }
137+
137138impl MetadataStrategy for DerivedMetadata { }
138139
139- impl < ' a > OfferBuilder < ' a , ExplicitMetadata , secp256k1:: SignOnly > {
140+ macro_rules! offer_explicit_metadata_builder_methods { (
141+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
142+ ) => {
140143 /// Creates a new builder for an offer setting the [`Offer::description`] and using the
141144 /// [`Offer::signing_pubkey`] for signing invoices. The associated secret key must be remembered
142145 /// while the offer is valid.
@@ -151,7 +154,7 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> {
151154 /// [`ChannelManager`]: crate::ln::channelmanager::ChannelManager
152155 /// [`ChannelManager::create_offer_builder`]: crate::ln::channelmanager::ChannelManager::create_offer_builder
153156 pub fn new( description: String , signing_pubkey: PublicKey ) -> Self {
154- OfferBuilder {
157+ Self {
155158 offer: OfferContents {
156159 chains: None , metadata: None , amount: None , description,
157160 features: OfferFeatures :: empty( ) , absolute_expiry: None , issuer: None , paths: None ,
@@ -165,13 +168,13 @@ impl<'a> OfferBuilder<'a, ExplicitMetadata, secp256k1::SignOnly> {
165168 /// Sets the [`Offer::metadata`] to the given bytes.
166169 ///
167170 /// Successive calls to this method will override the previous setting.
168- pub fn metadata ( mut self , metadata : Vec < u8 > ) -> Result < Self , Bolt12SemanticError > {
169- self . offer . metadata = Some ( Metadata :: Bytes ( metadata) ) ;
170- Ok ( self )
171+ pub fn metadata( mut $ self: $self_type , metadata: Vec <u8 >) -> Result <$return_type , Bolt12SemanticError > {
172+ $ self. offer. metadata = Some ( Metadata :: Bytes ( metadata) ) ;
173+ Ok ( $return_value )
171174 }
172- }
175+ } }
173176
174- impl < ' a , T : secp256k1 :: Signing > OfferBuilder < ' a , DerivedMetadata , T > {
177+ macro_rules! offer_derived_metadata_builder_methods { ( ) = > {
175178 /// Similar to [`OfferBuilder::new`] except, if [`OfferBuilder::path`] is called, the signing
176179 /// pubkey is derived from the given [`ExpandedKey`] and [`EntropySource`]. This provides
177180 /// recipient privacy by using a different signing pubkey for each offer. Otherwise, the
@@ -190,7 +193,7 @@ impl<'a, T: secp256k1::Signing> OfferBuilder<'a, DerivedMetadata, T> {
190193 let nonce = Nonce :: from_entropy_source( entropy_source) ;
191194 let derivation_material = MetadataMaterial :: new( nonce, expanded_key, IV_BYTES , None ) ;
192195 let metadata = Metadata :: DerivedSigningPubkey ( derivation_material) ;
193- OfferBuilder {
196+ Self {
194197 offer: OfferContents {
195198 chains: None , metadata: Some ( metadata) , amount: None , description,
196199 features: OfferFeatures :: empty( ) , absolute_expiry: None , issuer: None , paths: None ,
@@ -200,17 +203,19 @@ impl<'a, T: secp256k1::Signing> OfferBuilder<'a, DerivedMetadata, T> {
200203 secp_ctx: Some ( secp_ctx) ,
201204 }
202205 }
203- }
206+ } }
204207
205- impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
208+ macro_rules! offer_builder_methods { (
209+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
210+ ) => {
206211 /// Adds the chain hash of the given [`Network`] to [`Offer::chains`]. If not called,
207212 /// the chain hash of [`Network::Bitcoin`] is assumed to be the only one supported.
208213 ///
209214 /// See [`Offer::chains`] on how this relates to the payment currency.
210215 ///
211216 /// Successive calls to this method will add another chain hash.
212- pub fn chain ( self , network : Network ) -> Self {
213- self . chain_hash ( ChainHash :: using_genesis_block ( network) )
217+ pub fn chain( $ self: $self_type , network: Network ) -> $return_type {
218+ $ self. chain_hash( ChainHash :: using_genesis_block( network) )
214219 }
215220
216221 /// Adds the [`ChainHash`] to [`Offer::chains`]. If not called, the chain hash of
@@ -219,69 +224,69 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> {
219224 /// See [`Offer::chains`] on how this relates to the payment currency.
220225 ///
221226 /// Successive calls to this method will add another chain hash.
222- pub ( crate ) fn chain_hash ( mut self , chain : ChainHash ) -> Self {
223- let chains = self . offer . chains . get_or_insert_with ( Vec :: new) ;
227+ pub ( crate ) fn chain_hash( mut $ self: $self_type , chain: ChainHash ) -> $return_type {
228+ let chains = $ self. offer. chains. get_or_insert_with( Vec :: new) ;
224229 if !chains. contains( & chain) {
225230 chains. push( chain) ;
226231 }
227232
228- self
233+ $return_value
229234 }
230235
231236 /// Sets the [`Offer::amount`] as an [`Amount::Bitcoin`].
232237 ///
233238 /// Successive calls to this method will override the previous setting.
234- pub fn amount_msats ( self , amount_msats : u64 ) -> Self {
235- self . amount ( Amount :: Bitcoin { amount_msats } )
239+ pub fn amount_msats( $ self: $self_type , amount_msats: u64 ) -> $return_type {
240+ $ self. amount( Amount :: Bitcoin { amount_msats } )
236241 }
237242
238243 /// Sets the [`Offer::amount`].
239244 ///
240245 /// Successive calls to this method will override the previous setting.
241- pub ( super ) fn amount ( mut self , amount : Amount ) -> Self {
242- self . offer . amount = Some ( amount) ;
243- self
246+ pub ( super ) fn amount( mut $ self: $self_type , amount: Amount ) -> $return_type {
247+ $ self. offer. amount = Some ( amount) ;
248+ $return_value
244249 }
245250
246251 /// Sets the [`Offer::absolute_expiry`] as seconds since the Unix epoch. Any expiry that has
247252 /// already passed is valid and can be checked for using [`Offer::is_expired`].
248253 ///
249254 /// Successive calls to this method will override the previous setting.
250- pub fn absolute_expiry ( mut self , absolute_expiry : Duration ) -> Self {
251- self . offer . absolute_expiry = Some ( absolute_expiry) ;
252- self
255+ pub fn absolute_expiry( mut $ self: $self_type , absolute_expiry: Duration ) -> $return_type {
256+ $ self. offer. absolute_expiry = Some ( absolute_expiry) ;
257+ $return_value
253258 }
254259
255260 /// Sets the [`Offer::issuer`].
256261 ///
257262 /// Successive calls to this method will override the previous setting.
258- pub fn issuer ( mut self , issuer : String ) -> Self {
259- self . offer . issuer = Some ( issuer) ;
260- self
263+ pub fn issuer( mut $ self: $self_type , issuer: String ) -> $return_type {
264+ $ self. offer. issuer = Some ( issuer) ;
265+ $return_value
261266 }
262267
263268 /// Adds a blinded path to [`Offer::paths`]. Must include at least one path if only connected by
264269 /// private channels or if [`Offer::signing_pubkey`] is not a public node id.
265270 ///
266271 /// Successive calls to this method will add another blinded path. Caller is responsible for not
267272 /// adding duplicate paths.
268- pub fn path ( mut self , path : BlindedPath ) -> Self {
269- self . offer . paths . get_or_insert_with ( Vec :: new) . push ( path) ;
270- self
273+ pub fn path( mut $ self: $self_type , path: BlindedPath ) -> $return_type {
274+ $ self. offer. paths. get_or_insert_with( Vec :: new) . push( path) ;
275+ $return_value
271276 }
272277
273278 /// Sets the quantity of items for [`Offer::supported_quantity`]. If not called, defaults to
274279 /// [`Quantity::One`].
275280 ///
276281 /// Successive calls to this method will override the previous setting.
277- pub fn supported_quantity ( mut self , quantity : Quantity ) -> Self {
278- self . offer . supported_quantity = quantity;
279- self
282+ pub fn supported_quantity( mut $ self: $self_type , quantity: Quantity ) -> $return_type {
283+ $ self. offer. supported_quantity = quantity;
284+ $return_value
280285 }
281286
282287 /// Builds an [`Offer`] from the builder's settings.
283- pub fn build ( mut self ) -> Result < Offer , Bolt12SemanticError > {
284- match self . offer . amount {
288+ pub fn build( mut $ self: $self_type ) -> Result <Offer , Bolt12SemanticError > {
289+ match $ self. offer. amount {
285290 Some ( Amount :: Bitcoin { amount_msats } ) => {
286291 if amount_msats > MAX_VALUE_MSAT {
287292 return Err ( Bolt12SemanticError :: InvalidAmount ) ;
@@ -291,62 +296,79 @@ impl<'a, M: MetadataStrategy, T: secp256k1::Signing> OfferBuilder<'a, M, T> {
291296 None => { } ,
292297 }
293298
294- if let Some ( chains) = & self . offer . chains {
295- if chains. len ( ) == 1 && chains[ 0 ] == self . offer . implied_chain ( ) {
296- self . offer . chains = None ;
299+ if let Some ( chains) = & $ self. offer. chains {
300+ if chains. len( ) == 1 && chains[ 0 ] == $ self. offer. implied_chain( ) {
301+ $ self. offer. chains = None ;
297302 }
298303 }
299304
300- Ok ( self . build_without_checks ( ) )
305+ Ok ( $ self. build_without_checks( ) )
301306 }
302307
303- fn build_without_checks ( mut self ) -> Offer {
308+ fn build_without_checks( mut $ self: $self_type ) -> Offer {
304309 // Create the metadata for stateless verification of an InvoiceRequest.
305- if let Some ( mut metadata) = self . offer . metadata . take ( ) {
310+ if let Some ( mut metadata) = $ self. offer. metadata. take( ) {
306311 if metadata. has_derivation_material( ) {
307- if self . offer . paths . is_none ( ) {
312+ if $ self. offer. paths. is_none( ) {
308313 metadata = metadata. without_keys( ) ;
309314 }
310315
311- let mut tlv_stream = self . offer . as_tlv_stream ( ) ;
316+ let mut tlv_stream = $ self. offer. as_tlv_stream( ) ;
312317 debug_assert_eq!( tlv_stream. metadata, None ) ;
313318 tlv_stream. metadata = None ;
314319 if metadata. derives_recipient_keys( ) {
315320 tlv_stream. node_id = None ;
316321 }
317322
318- let ( derived_metadata, keys) = metadata. derive_from ( tlv_stream, self . secp_ctx ) ;
323+ let ( derived_metadata, keys) = metadata. derive_from( tlv_stream, $ self. secp_ctx) ;
319324 metadata = derived_metadata;
320325 if let Some ( keys) = keys {
321- self . offer . signing_pubkey = keys. public_key ( ) ;
326+ $ self. offer. signing_pubkey = keys. public_key( ) ;
322327 }
323328 }
324329
325- self . offer . metadata = Some ( metadata) ;
330+ $ self. offer. metadata = Some ( metadata) ;
326331 }
327332
328333 let mut bytes = Vec :: new( ) ;
329- self . offer . write ( & mut bytes) . unwrap ( ) ;
334+ $ self. offer. write( & mut bytes) . unwrap( ) ;
330335
331- Offer { bytes, contents : self . offer }
336+ Offer { bytes, contents: $ self. offer }
332337 }
333- }
338+ } }
334339
335340#[ cfg( test) ]
336- impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
337- fn features_unchecked ( mut self , features : OfferFeatures ) -> Self {
338- self . offer . features = features;
339- self
341+ macro_rules! offer_builder_test_methods { (
342+ $self: ident, $self_type: ty, $return_type: ty, $return_value: expr
343+ ) => {
344+ fn features_unchecked( mut $self: $self_type, features: OfferFeatures ) -> $return_type {
345+ $self. offer. features = features;
346+ $return_value
340347 }
341348
342- pub ( crate ) fn clear_paths ( mut self ) -> Self {
343- self . offer . paths = None ;
344- self
349+ pub ( crate ) fn clear_paths( mut $ self: $self_type ) -> $return_type {
350+ $ self. offer. paths = None ;
351+ $return_value
345352 }
346353
347- pub ( super ) fn build_unchecked ( self ) -> Offer {
348- self . build_without_checks ( )
354+ pub ( super ) fn build_unchecked( $ self: $self_type ) -> Offer {
355+ $ self. build_without_checks( )
349356 }
357+ } }
358+
359+ impl < ' a , M : MetadataStrategy , T : secp256k1:: Signing > OfferBuilder < ' a , M , T > {
360+ offer_builder_methods ! ( self , Self , Self , self ) ;
361+
362+ #[ cfg( test) ]
363+ offer_builder_test_methods ! ( self , Self , Self , self ) ;
364+ }
365+
366+ impl < ' a > OfferBuilder < ' a , ExplicitMetadata , secp256k1:: SignOnly > {
367+ offer_explicit_metadata_builder_methods ! ( self , Self , Self , self ) ;
368+ }
369+
370+ impl < ' a , T : secp256k1:: Signing > OfferBuilder < ' a , DerivedMetadata , T > {
371+ offer_derived_metadata_builder_methods ! ( ) ;
350372}
351373
352374/// An `Offer` is a potentially long-lived proposal for payment of a good or service.
0 commit comments