@@ -57,7 +57,7 @@ Then, within a Rust source file:
5757
5858```ignore
5959
60- bare_gen::bare_schema("schema.bare"); // TokenStream
60+ bare_gen::bare_schema("schema.bare", bare_gen::Config::default() ); // TokenStream
6161
6262```
6363
@@ -71,8 +71,8 @@ as cleanly or require additional explanation.
7171
7272## Maps
7373
74- BARE maps are interpreted as `HashMap<K, V>` in Rust. As of now, this is not configurable, but
75- may be in the future .
74+ BARE maps are interpreted as `std::collections:: HashMap<K, V>` in Rust by default. Set
75+ `Config::use_hashable_map` to `true` to emit `rivet_util::serde::HashableMap<K, V>` instead .
7676
7777## Variable Length Integers
7878
@@ -94,6 +94,35 @@ use quote::quote;
9494
9595mod parser;
9696
97+ /// Configuration for `bare_schema` code generation.
98+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
99+ pub struct Config {
100+ /// When true, generated maps use `rivet_util::serde::HashableMap`.
101+ pub use_hashable_map : bool ,
102+ }
103+
104+ impl Default for Config {
105+ fn default ( ) -> Self {
106+ Self {
107+ use_hashable_map : false ,
108+ }
109+ }
110+ }
111+
112+ impl Config {
113+ /// Convenience constructor to emit `HashMap` rather than `HashableMap`.
114+ pub fn with_hash_map ( ) -> Self {
115+ Self :: default ( )
116+ }
117+
118+ /// Convenience constructor to emit `HashableMap`.
119+ pub fn with_hashable_map ( ) -> Self {
120+ Self {
121+ use_hashable_map : true ,
122+ }
123+ }
124+ }
125+
97126fn ident_from_string ( s : & String ) -> Ident {
98127 Ident :: new ( s, Span :: call_site ( ) )
99128}
@@ -104,11 +133,12 @@ fn ident_from_string(s: &String) -> Ident {
104133/// path is treated as relative to the file location of the macro's use.
105134/// For details on how the BARE data model maps to the Rust data model, see the [`Serialize`
106135/// derive macro's documentation.](https://docs.rs/serde_bare/latest/serde_bare/)
107- pub fn bare_schema ( schema_path : & Path ) -> proc_macro2:: TokenStream {
136+ pub fn bare_schema ( schema_path : & Path , config : Config ) -> proc_macro2:: TokenStream {
108137 let file = read_to_string ( schema_path) . unwrap ( ) ;
109138 let mut schema_generator = SchemaGenerator {
110139 global_output : Default :: default ( ) ,
111140 user_type_registry : parse_string ( & file) ,
141+ config,
112142 } ;
113143
114144 for ( name, user_type) in & schema_generator. user_type_registry . clone ( ) {
@@ -121,22 +151,24 @@ pub fn bare_schema(schema_path: &Path) -> proc_macro2::TokenStream {
121151struct SchemaGenerator {
122152 global_output : Vec < TokenStream > ,
123153 user_type_registry : BTreeMap < String , AnyType > ,
154+ config : Config ,
124155}
125156
126157impl SchemaGenerator {
127158 /// Completes a generation cycle by consuming the `SchemaGenerator` and yielding a
128159 /// `TokenStream`.
129160 fn complete ( self ) -> TokenStream {
130- let user_type_syntax = self . global_output ;
161+ let SchemaGenerator {
162+ global_output,
163+ ..
164+ } = self ;
131165 quote ! {
132- #[ allow( unused_imports) ]
133- use rivet_util:: serde:: HashableMap ;
134166 #[ allow( unused_imports) ]
135167 use serde:: { Serialize , Deserialize } ;
136168 #[ allow( unused_imports) ]
137169 use serde_bare:: { Uint , Int } ;
138170
139- #( #user_type_syntax ) *
171+ #( #global_output ) *
140172 }
141173 }
142174
@@ -217,8 +249,14 @@ impl SchemaGenerator {
217249 fn gen_map ( & mut self , name : & String , key : & AnyType , value : & AnyType ) -> TokenStream {
218250 let key_def = self . dispatch_type ( name, key) ;
219251 let val_def = self . dispatch_type ( name, value) ;
220- quote ! {
221- HashableMap <#key_def, #val_def>
252+ if self . config . use_hashable_map {
253+ quote ! {
254+ rivet_util:: serde:: HashableMap <#key_def, #val_def>
255+ }
256+ } else {
257+ quote ! {
258+ std:: collections:: HashMap <#key_def, #val_def>
259+ }
222260 }
223261 }
224262
@@ -243,9 +281,14 @@ impl SchemaGenerator {
243281 // clone so we can safely drain this
244282 let fields_clone = fields. clone ( ) ;
245283 let fields_gen = self . gen_struct_field ( name, fields_clone) ;
284+ let hash_derive = if self . config . use_hashable_map {
285+ quote ! { , Hash }
286+ } else {
287+ TokenStream :: new ( )
288+ } ;
246289 self . gen_anonymous ( name, |ident| {
247290 quote ! {
248- #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , Clone , Hash ) ]
291+ #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , Clone #hash_derive ) ]
249292 pub struct #ident {
250293 #( #fields_gen) , *
251294 }
@@ -296,9 +339,14 @@ impl SchemaGenerator {
296339 } ;
297340 members_def. push ( member_def) ;
298341 }
342+ let hash_derive = if self . config . use_hashable_map {
343+ quote ! { , Hash }
344+ } else {
345+ TokenStream :: new ( )
346+ } ;
299347 self . gen_anonymous ( name, |ident| {
300348 quote ! {
301- #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , Clone , Hash ) ]
349+ #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , Clone #hash_derive ) ]
302350 pub enum #ident {
303351 #( #members_def) , *
304352 }
@@ -344,9 +392,14 @@ impl SchemaGenerator {
344392 }
345393 }
346394 } ) ;
395+ let hash_derive = if self . config . use_hashable_map {
396+ quote ! { Hash , }
397+ } else {
398+ TokenStream :: new ( )
399+ } ;
347400 self . gen_anonymous ( name, |ident| {
348401 quote ! {
349- #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , PartialOrd , Ord , Hash , Clone ) ]
402+ #[ derive( Serialize , Deserialize , PartialEq , Eq , Debug , PartialOrd , Ord , #hash_derive Clone ) ]
350403 #[ repr( usize ) ]
351404 pub enum #ident {
352405 #( #member_defs) , *
@@ -396,4 +449,3 @@ fn gen_primative_type_def(p: &PrimativeType) -> TokenStream {
396449 Bool => quote ! { bool } ,
397450 }
398451}
399-
0 commit comments