@@ -71,11 +71,11 @@ pub struct DataResponseMetadata {
71
71
///
72
72
/// assert_eq!("Demo", payload.get().message);
73
73
/// ```
74
- pub struct DataPayload < M >
75
- where
76
- M : DataMarker ,
77
- {
78
- pub ( crate ) yoke : Yoke < M :: Yokeable , Option < Cart > > ,
74
+ pub struct DataPayload < M : DataMarker > ( pub ( crate ) DataPayloadInner < M > ) ;
75
+
76
+ pub ( crate ) enum DataPayloadInner < M : DataMarker > {
77
+ Yoke ( Yoke < M :: Yokeable , Option < Cart > > ) ,
78
+ Ref ( & ' static M :: Yokeable ) ,
79
79
}
80
80
81
81
/// The type of the "cart" that is used by `DataPayload`.
@@ -136,9 +136,10 @@ where
136
136
for < ' a > YokeTraitHack < <M :: Yokeable as Yokeable < ' a > >:: Output > : Clone ,
137
137
{
138
138
fn clone ( & self ) -> Self {
139
- Self {
140
- yoke : self . yoke . clone ( ) ,
141
- }
139
+ Self ( match & self . 0 {
140
+ DataPayloadInner :: Yoke ( yoke) => DataPayloadInner :: Yoke ( yoke. clone ( ) ) ,
141
+ DataPayloadInner :: Ref ( r) => DataPayloadInner :: Ref ( * r) ,
142
+ } )
142
143
}
143
144
}
144
145
@@ -193,17 +194,23 @@ where
193
194
/// ```
194
195
#[ inline]
195
196
pub fn from_owned ( data : M :: Yokeable ) -> Self {
196
- Self {
197
- yoke : Yoke :: new_owned ( data) ,
198
- }
197
+ Self ( DataPayloadInner :: Yoke ( Yoke :: new_owned ( data) ) )
198
+ }
199
+
200
+ #[ doc( hidden) ]
201
+ #[ inline]
202
+ pub fn from_static_ref ( data : & ' static M :: Yokeable ) -> Self {
203
+ Self ( DataPayloadInner :: Ref ( data) )
199
204
}
200
205
201
206
/// Convert a DataPayload that was created via [`DataPayload::from_owned()`] back into the
202
207
/// concrete type used to construct it.
203
208
pub fn try_unwrap_owned ( self ) -> Result < M :: Yokeable , DataError > {
204
- self . yoke
205
- . try_into_yokeable ( )
206
- . map_err ( |_| DataErrorKind :: InvalidState . with_str_context ( "try_unwrap_owned" ) )
209
+ match self . 0 {
210
+ DataPayloadInner :: Yoke ( yoke) => yoke. try_into_yokeable ( ) . ok ( ) ,
211
+ DataPayloadInner :: Ref ( _) => None ,
212
+ }
213
+ . ok_or ( DataErrorKind :: InvalidState . with_str_context ( "try_unwrap_owned" ) )
207
214
}
208
215
209
216
/// Mutate the data contained in this DataPayload.
@@ -244,8 +251,15 @@ where
244
251
pub fn with_mut < ' a , F > ( & ' a mut self , f : F )
245
252
where
246
253
F : ' static + for < ' b > FnOnce ( & ' b mut <M :: Yokeable as Yokeable < ' a > >:: Output ) ,
254
+ M :: Yokeable : Clone ,
247
255
{
248
- self . yoke . with_mut ( f)
256
+ if let DataPayloadInner :: Ref ( r) = self . 0 {
257
+ self . 0 = DataPayloadInner :: Yoke ( Yoke :: new_owned ( M :: Yokeable :: clone ( r) ) ) ;
258
+ }
259
+ match & mut self . 0 {
260
+ DataPayloadInner :: Yoke ( yoke) => yoke. with_mut ( f) ,
261
+ _ => unreachable ! ( ) ,
262
+ }
249
263
}
250
264
251
265
/// Borrows the underlying data.
@@ -266,7 +280,10 @@ where
266
280
#[ inline]
267
281
#[ allow( clippy:: needless_lifetimes) ]
268
282
pub fn get < ' a > ( & ' a self ) -> & ' a <M :: Yokeable as Yokeable < ' a > >:: Output {
269
- self . yoke . get ( )
283
+ match & self . 0 {
284
+ DataPayloadInner :: Yoke ( yoke) => yoke. get ( ) ,
285
+ DataPayloadInner :: Ref ( r) => Yokeable :: transform ( * r) ,
286
+ }
270
287
}
271
288
272
289
/// Maps `DataPayload<M>` to `DataPayload<M2>` by projecting it with [`Yoke::map_project`].
@@ -318,10 +335,14 @@ where
318
335
<M :: Yokeable as Yokeable < ' a > >:: Output ,
319
336
PhantomData < & ' a ( ) > ,
320
337
) -> <M2 :: Yokeable as Yokeable < ' a > >:: Output ,
338
+ M :: Yokeable : Clone ,
321
339
{
322
- DataPayload {
323
- yoke : self . yoke . map_project ( f) ,
324
- }
340
+ DataPayload ( match self . 0 {
341
+ DataPayloadInner :: Yoke ( yoke) => DataPayloadInner :: Yoke ( yoke. map_project ( f) ) ,
342
+ DataPayloadInner :: Ref ( r) => {
343
+ DataPayloadInner :: Yoke ( Yoke :: new_owned ( r. clone ( ) ) . map_project ( f) )
344
+ }
345
+ } )
325
346
}
326
347
327
348
/// Version of [`DataPayload::map_project()`] that borrows `self` instead of moving `self`.
@@ -362,8 +383,16 @@ where
362
383
PhantomData < & ' a ( ) > ,
363
384
) -> <M2 :: Yokeable as Yokeable < ' a > >:: Output ,
364
385
{
365
- DataPayload {
366
- yoke : self . yoke . map_project_cloned ( f) ,
386
+ match & self . 0 {
387
+ DataPayloadInner :: Yoke ( yoke) => {
388
+ DataPayload ( DataPayloadInner :: Yoke ( yoke. map_project_cloned ( f) ) )
389
+ }
390
+ DataPayloadInner :: Ref ( r) => {
391
+ let output: <M2 :: Yokeable as Yokeable < ' static > >:: Output =
392
+ f ( Yokeable :: transform ( * r) , PhantomData ) ;
393
+ let yokeable: M2 :: Yokeable = unsafe { M2 :: Yokeable :: make ( output) } ;
394
+ DataPayload ( DataPayloadInner :: Yoke ( Yoke :: new_owned ( yokeable) ) )
395
+ }
367
396
}
368
397
}
369
398
@@ -411,10 +440,14 @@ where
411
440
<M :: Yokeable as Yokeable < ' a > >:: Output ,
412
441
PhantomData < & ' a ( ) > ,
413
442
) -> Result < <M2 :: Yokeable as Yokeable < ' a > >:: Output , E > ,
443
+ M :: Yokeable : Clone ,
414
444
{
415
- Ok ( DataPayload {
416
- yoke : self . yoke . try_map_project ( f) ?,
417
- } )
445
+ Ok ( DataPayload ( match self . 0 {
446
+ DataPayloadInner :: Yoke ( yoke) => DataPayloadInner :: Yoke ( yoke. try_map_project ( f) ?) ,
447
+ DataPayloadInner :: Ref ( r) => {
448
+ DataPayloadInner :: Yoke ( Yoke :: new_owned ( r. clone ( ) ) . try_map_project ( f) ?)
449
+ }
450
+ } ) )
418
451
}
419
452
420
453
/// Version of [`DataPayload::map_project_cloned()`] that bubbles up an error from `f`.
@@ -465,8 +498,16 @@ where
465
498
PhantomData < & ' a ( ) > ,
466
499
) -> Result < <M2 :: Yokeable as Yokeable < ' a > >:: Output , E > ,
467
500
{
468
- Ok ( DataPayload {
469
- yoke : self . yoke . try_map_project_cloned ( f) ?,
501
+ Ok ( match & self . 0 {
502
+ DataPayloadInner :: Yoke ( yoke) => {
503
+ DataPayload ( DataPayloadInner :: Yoke ( yoke. try_map_project_cloned ( f) ?) )
504
+ }
505
+ DataPayloadInner :: Ref ( r) => {
506
+ let output: <M2 :: Yokeable as Yokeable < ' static > >:: Output =
507
+ f ( Yokeable :: transform ( * r) , PhantomData ) ?;
508
+ let yokeable: M2 :: Yokeable = unsafe { M2 :: Yokeable :: make ( output) } ;
509
+ DataPayload ( DataPayloadInner :: Yoke ( Yoke :: new_owned ( yokeable) ) )
510
+ }
470
511
} )
471
512
}
472
513
@@ -497,7 +538,10 @@ where
497
538
where
498
539
M2 : DataMarker < Yokeable = M :: Yokeable > ,
499
540
{
500
- DataPayload { yoke : self . yoke }
541
+ DataPayload ( match self . 0 {
542
+ DataPayloadInner :: Yoke ( yoke) => DataPayloadInner :: Yoke ( yoke) ,
543
+ DataPayloadInner :: Ref ( r) => DataPayloadInner :: Ref ( r) ,
544
+ } )
501
545
}
502
546
}
503
547
@@ -507,19 +551,17 @@ impl DataPayload<BufferMarker> {
507
551
let yoke = Yoke :: attach_to_cart ( SelectedRc :: new ( buffer) , |b| & * * b) ;
508
552
// Safe because cart is wrapped
509
553
let yoke = unsafe { yoke. replace_cart ( |b| Some ( Cart ( b) ) ) } ;
510
- Self { yoke }
554
+ Self ( DataPayloadInner :: Yoke ( yoke) )
511
555
}
512
556
513
557
/// Converts a yoked byte buffer into a `DataPayload<BufferMarker>`.
514
558
pub fn from_yoked_buffer ( yoke : Yoke < & ' static [ u8 ] , Option < Cart > > ) -> Self {
515
- Self { yoke }
559
+ Self ( DataPayloadInner :: Yoke ( yoke) )
516
560
}
517
561
518
562
/// Converts a static byte buffer into a `DataPayload<BufferMarker>`.
519
- pub fn from_static_buffer ( buffer : & ' static [ u8 ] ) -> Self {
520
- Self {
521
- yoke : Yoke :: new_owned ( buffer) ,
522
- }
563
+ pub fn from_static_buffer ( buffer : & ' static & ' static [ u8 ] ) -> Self {
564
+ Self ( DataPayloadInner :: Ref ( buffer) )
523
565
}
524
566
}
525
567
0 commit comments