@@ -102,14 +102,6 @@ use std::io::Write;
102
102
use std:: path:: PathBuf ;
103
103
use std:: sync:: Mutex ;
104
104
105
- macro_rules! move_out {
106
- ( $field: expr) => { {
107
- let mut tmp = Default :: default ( ) ;
108
- core:: mem:: swap( & mut tmp, & mut $field) ;
109
- tmp
110
- } } ;
111
- }
112
-
113
105
// TokenStream isn't Send/Sync
114
106
type SyncTokenStream = String ;
115
107
@@ -170,7 +162,7 @@ pub struct BakedExporter {
170
162
BTreeMap < SyncTokenStream , HashSet < ( DataLocale , DataMarkerAttributes ) > > ,
171
163
> ,
172
164
> ,
173
- /// (Key, Marker ) pairs to wire up in mod.rs. This is populated by `flush` and consumed by `close`.
165
+ /// (marker, file name ) pairs to wire up in mod.rs. This is populated by `flush` and consumed by `close`.
174
166
impl_data : Mutex < BTreeMap < DataMarkerInfo , SyncTokenStream > > ,
175
167
// List of dependencies used by baking.
176
168
dependencies : CrateEnv ,
@@ -276,7 +268,7 @@ impl BakedExporter {
276
268
}
277
269
278
270
fn print_deps ( & mut self ) {
279
- let mut deps = move_out ! ( self . dependencies)
271
+ let mut deps = core :: mem :: take ( & mut self . dependencies )
280
272
. into_iter ( )
281
273
. collect :: < BTreeSet < _ > > ( ) ;
282
274
if !self . use_separate_crates {
@@ -298,33 +290,44 @@ impl BakedExporter {
298
290
299
291
fn write_impl_macros (
300
292
& self ,
293
+ marker : DataMarkerInfo ,
301
294
body : TokenStream ,
302
295
iterable_body : TokenStream ,
303
- marker : DataMarkerInfo ,
304
- marker_bake : TokenStream ,
305
296
) -> Result < ( ) , DataError > {
306
- let marker_string = marker_bake . to_string ( ) ;
307
- let marker_last = marker_bake . into_iter ( ) . last ( ) . unwrap ( ) ;
297
+ let marker_unqualified = bake_marker ( marker ) . into_iter ( ) . last ( ) . unwrap ( ) ;
298
+
308
299
let doc = format ! (
309
300
" Implement `DataProvider<{}>` on the given struct using the data" ,
310
- marker_last
301
+ marker_unqualified
311
302
) ;
312
303
let doc_iterable = format ! (
313
304
" Implement `IterableDataProvider<{}>` on the given struct using the data" ,
314
- marker_last
305
+ marker_unqualified
315
306
) ;
316
307
317
- let ident = Self :: ident ( marker) ;
308
+ let ident = marker
309
+ . path
310
+ . replace ( '/' , "_" )
311
+ . replace ( '@' , "_v" )
312
+ . to_ascii_lowercase ( ) ;
313
+
314
+ let macro_ident = format ! ( "impl_{ident}" , ) . parse :: < TokenStream > ( ) . unwrap ( ) ;
315
+ let macro_ident_iterable = format ! ( "impliterable_{ident}" )
316
+ . parse :: < TokenStream > ( )
317
+ . unwrap ( ) ;
318
318
319
- let prefixed_macro_ident = format ! ( "__impl_{ident}" ) . parse :: < TokenStream > ( ) . unwrap ( ) ;
320
- let prefixed_macro_ident_iterable = format ! ( "__impliterable_{ident}" )
319
+ // We prefix all macros with `__`, as these will be automatically exported at the crate root, which is annoying
320
+ // for crates that include the data but don't want it to be public. We then reexport them as items that use
321
+ // normal scoping that clients can control.
322
+ let prefixed_macro_ident = format ! ( "__{macro_ident}" ) . parse :: < TokenStream > ( ) . unwrap ( ) ;
323
+ let prefixed_macro_ident_iterable = format ! ( "__{macro_ident_iterable}" )
321
324
. parse :: < TokenStream > ( )
322
325
. unwrap ( ) ;
323
326
324
327
let maybe_msrv = maybe_msrv ( ) ;
325
328
326
329
self . write_to_file (
327
- PathBuf :: from ( format ! ( "macros/{ }.rs.data" , ident ) ) ,
330
+ PathBuf :: from ( format ! ( "{ident }.rs.data" ) ) ,
328
331
quote ! {
329
332
#[ doc = #doc]
330
333
/// hardcoded in this file. This allows the struct to be used with
@@ -338,6 +341,9 @@ impl BakedExporter {
338
341
#body
339
342
}
340
343
}
344
+ #[ doc( inline) ]
345
+ pub use #prefixed_macro_ident as #macro_ident;
346
+
341
347
#[ doc = #doc_iterable]
342
348
/// hardcoded in this file. This allows the struct to be used with
343
349
/// `DatagenDriver` for this marker.
@@ -348,23 +354,14 @@ impl BakedExporter {
348
354
#iterable_body
349
355
}
350
356
}
357
+ #[ doc( inline) ]
358
+ pub use #prefixed_macro_ident_iterable as #macro_ident_iterable;
351
359
} ,
352
360
) ?;
353
361
354
- self . impl_data
355
- . lock ( )
356
- . expect ( "poison" )
357
- . insert ( marker, marker_string) ;
362
+ self . impl_data . lock ( ) . expect ( "poison" ) . insert ( marker, ident) ;
358
363
Ok ( ( ) )
359
364
}
360
-
361
- fn ident ( marker : DataMarkerInfo ) -> String {
362
- marker
363
- . path
364
- . to_ascii_lowercase ( )
365
- . replace ( '@' , "_v" )
366
- . replace ( '/' , "_" )
367
- }
368
365
}
369
366
370
367
impl DataExporter for BakedExporter {
@@ -393,17 +390,25 @@ impl DataExporter for BakedExporter {
393
390
marker : DataMarkerInfo ,
394
391
payload : & DataPayload < ExportMarker > ,
395
392
) -> Result < ( ) , DataError > {
396
- let marker_bake = bake_marker ( marker, & self . dependencies ) ;
397
-
398
- let singleton_ident = format ! ( "SINGLETON_{}" , Self :: ident( marker) . to_ascii_uppercase( ) )
399
- . parse :: < TokenStream > ( )
400
- . unwrap ( ) ;
393
+ let marker_bake = bake_marker ( marker) ;
394
+
395
+ let singleton_ident = format ! (
396
+ "SINGLETON_{}" ,
397
+ marker
398
+ . path
399
+ . get( )
400
+ . replace( '/' , "_" )
401
+ . replace( '@' , "_v" )
402
+ . to_ascii_uppercase( )
403
+ )
404
+ . parse :: < TokenStream > ( )
405
+ . unwrap ( ) ;
401
406
402
407
let bake = payload. tokenize ( & self . dependencies ) ;
403
408
404
409
let maybe_msrv = maybe_msrv ( ) ;
405
410
406
- self . write_impl_macros ( quote ! {
411
+ self . write_impl_macros ( marker , quote ! {
407
412
#maybe_msrv
408
413
impl $provider {
409
414
// Exposing singleton structs as consts allows us to get rid of fallibility
@@ -434,11 +439,11 @@ impl DataExporter for BakedExporter {
434
439
Ok ( HashSet :: from_iter( [ Default :: default ( ) ] ) )
435
440
}
436
441
}
437
- } , marker , marker_bake )
442
+ } )
438
443
}
439
444
440
445
fn flush ( & self , marker : DataMarkerInfo ) -> Result < ( ) , DataError > {
441
- let marker_bake = bake_marker ( marker, & self . dependencies ) ;
446
+ let marker_bake = bake_marker ( marker) ;
442
447
443
448
let ( struct_type, into_data_payload) = if marker_bake
444
449
. to_string ( )
@@ -608,6 +613,7 @@ impl DataExporter for BakedExporter {
608
613
} ;
609
614
610
615
self . write_impl_macros (
616
+ marker,
611
617
quote ! {
612
618
#maybe_msrv
613
619
impl icu_provider:: DataProvider <#marker_bake> for $provider {
@@ -627,54 +633,34 @@ impl DataExporter for BakedExporter {
627
633
}
628
634
}
629
635
} ,
630
- marker,
631
- marker_bake,
632
636
)
633
637
}
634
638
635
639
fn close ( & mut self ) -> Result < ( ) , DataError > {
636
640
log:: info!( "Writing macros module..." ) ;
637
641
638
- let data = move_out ! ( self . impl_data) . into_inner ( ) . expect ( "poison" ) ;
639
-
640
- let marker_bakes = data
641
- . values ( )
642
- . map ( |marker| marker. parse :: < TokenStream > ( ) . unwrap ( ) )
643
- . collect :: < Vec < _ > > ( ) ;
644
-
645
- let (
646
- macro_idents,
647
- prefixed_macro_idents,
648
- macro_idents_iterable,
649
- prefixed_macro_idents_iterable,
650
- mod_idents,
651
- file_paths,
652
- ) : ( Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > , Vec < _ > ) =
653
- itertools:: multiunzip ( data. keys ( ) . map ( |& marker| {
654
- let ident = Self :: ident ( marker) ;
655
- (
656
- format ! ( "impl_{}" , ident) . parse :: < TokenStream > ( ) . unwrap ( ) ,
657
- // We prefix all macros with `__`, as these will be automatically exported at the crate root, which is annoying
658
- // for crates that include the data but don't want it to be public. We then reexport them as items that use
659
- // normal scoping that clients can control.
660
- format ! ( "__impl_{}" , ident) . parse :: < TokenStream > ( ) . unwrap ( ) ,
661
- format ! ( "impliterable_{}" , ident)
662
- . parse :: < TokenStream > ( )
663
- . unwrap ( ) ,
664
- format ! ( "__impliterable_{}" , ident)
665
- . parse :: < TokenStream > ( )
666
- . unwrap ( ) ,
667
- ident. parse :: < TokenStream > ( ) . unwrap ( ) ,
668
- format ! ( "macros/{}.rs.data" , ident) ,
669
- )
670
- } ) ) ;
642
+ let data = core:: mem:: take ( & mut self . impl_data )
643
+ . into_inner ( )
644
+ . expect ( "poison" ) ;
671
645
672
646
let maybe_msrv = maybe_msrv ( ) ;
673
647
674
- // macros.rs is the interface for built-in data. It exposes one macro per marker.
648
+ let marker_bakes = data. keys ( ) . copied ( ) . map ( bake_marker) ;
649
+
650
+ let file_paths = data. values ( ) . map ( |i| format ! ( "{i}.rs.data" ) ) ;
651
+
652
+ let macro_idents = data
653
+ . values ( )
654
+ . map ( |i| format ! ( "impl_{i}" ) . parse :: < TokenStream > ( ) . unwrap ( ) ) ;
655
+
656
+ // mod.rs is the interface for built-in data. It exposes one macro per marker.
675
657
self . write_to_file (
676
- PathBuf :: from ( "macros .rs" ) ,
658
+ PathBuf :: from ( "mod .rs" ) ,
677
659
quote ! {
660
+ #(
661
+ include!( #file_paths) ;
662
+ ) *
663
+
678
664
/// Marks a type as a data provider. You can then use macros like
679
665
/// `impl_core_helloworld_v1` to add implementations.
680
666
///
@@ -700,26 +686,9 @@ impl DataExporter for BakedExporter {
700
686
}
701
687
#[ doc( inline) ]
702
688
pub use __make_provider as make_provider;
703
- #(
704
- #[ macro_use]
705
- #[ path = #file_paths]
706
- mod #mod_idents;
707
- #[ doc( inline) ]
708
- pub use #prefixed_macro_idents as #macro_idents;
709
- #[ doc( inline) ]
710
- pub use #prefixed_macro_idents_iterable as #macro_idents_iterable;
711
- ) *
712
- } ,
713
- ) ?;
714
689
715
- // mod.rs is the interface for using databake directly. It exposes the macros from macros.rs,
716
- // as well as `impl_data_provider` and `impl_any_provider` which include all markers.
717
- self . write_to_file (
718
- PathBuf :: from ( "mod.rs" ) ,
719
- quote ! {
720
- include!( "macros.rs" ) ;
721
-
722
- // Not public as it will only work locally due to needing access to the macros from `macros.rs`.
690
+ // Not public as it will only work locally due to needing access to the other macros.
691
+ #[ allow( unused_macros) ]
723
692
macro_rules! impl_data_provider {
724
693
( $provider: ty) => {
725
694
make_provider!( $provider) ;
@@ -729,8 +698,7 @@ impl DataExporter for BakedExporter {
729
698
} ;
730
699
}
731
700
732
- // Not public because `impl_data_provider` isn't. Users can implement `DynamicDataProvider<AnyMarker>`
733
- // using `impl_dynamic_data_provider!`.
701
+ // Not public because `impl_data_provider` isn't.
734
702
#[ allow( unused_macros) ]
735
703
macro_rules! impl_any_provider {
736
704
( $provider: ty) => {
@@ -748,20 +716,6 @@ impl DataExporter for BakedExporter {
748
716
}
749
717
}
750
718
}
751
-
752
- // For backwards compatibility
753
- #maybe_msrv
754
- pub struct BakedDataProvider ;
755
- impl_data_provider!( BakedDataProvider ) ;
756
- } ,
757
- ) ?;
758
-
759
- // For backwards compatibility
760
- self . write_to_file (
761
- PathBuf :: from ( "any.rs" ) ,
762
- quote ! {
763
- // This assumes that `mod.rs` is already included.
764
- impl_any_provider!( BakedDataProvider ) ;
765
719
} ,
766
720
) ?;
767
721
@@ -773,20 +727,26 @@ impl DataExporter for BakedExporter {
773
727
774
728
macro_rules! cb {
775
729
( $( $marker: path = $path: literal, ) + #[ experimental] $( $emarker: path = $epath: literal, ) +) => {
776
- fn bake_marker( marker: DataMarkerInfo , _env : & databake :: CrateEnv ) -> databake:: TokenStream {
730
+ fn bake_marker( marker: DataMarkerInfo ) -> databake:: TokenStream {
777
731
if * marker. path == * icu_provider:: hello_world:: HelloWorldV1Marker :: INFO . path {
778
732
return databake:: quote!( icu_provider:: hello_world:: HelloWorldV1Marker ) ;
779
733
}
780
734
781
735
$(
782
736
if * marker. path == * $path {
783
- return databake:: quote!( $marker) ;
737
+ return stringify!( $marker)
738
+ . replace( "icu :: " , "icu_" )
739
+ . parse( )
740
+ . unwrap( ) ;
784
741
}
785
742
) +
786
743
787
744
$(
788
745
if * marker. path == * $epath {
789
- return databake:: quote!( $emarker) ;
746
+ return stringify!( $emarker)
747
+ . replace( "icu :: " , "icu_" )
748
+ . parse( )
749
+ . unwrap( ) ;
790
750
}
791
751
) +
792
752
0 commit comments