Skip to content

Commit 3072d8c

Browse files
committed
fix hashablemap gen
1 parent a7ce0c8 commit 3072d8c

File tree

3 files changed

+76
-46
lines changed

3 files changed

+76
-46
lines changed

STORY.md

Lines changed: 0 additions & 20 deletions
This file was deleted.

rust/vbare-compiler/src/lib.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ pub struct Config {
1313
impl Default for Config {
1414
fn default() -> Self {
1515
Self {
16-
vbare: vbare_gen::Config {
17-
use_hashable_map: false,
18-
},
16+
vbare: vbare_gen::Config::with_hash_map(),
1917
}
2018
}
2119
}
@@ -24,9 +22,14 @@ impl Config {
2422
/// Convenience helper to enable hashable maps in generated code.
2523
pub fn with_hashable_map() -> Self {
2624
Self {
27-
vbare: vbare_gen::Config {
28-
use_hashable_map: true,
29-
},
25+
vbare: vbare_gen::Config::with_hashable_map(),
26+
}
27+
}
28+
29+
/// Convenience helper to use the standard library `HashMap`.
30+
pub fn with_hash_map() -> Self {
31+
Self {
32+
vbare: vbare_gen::Config::with_hash_map(),
3033
}
3134
}
3235
}
@@ -64,12 +67,7 @@ pub fn process_schemas_with_config(
6467
.ok_or("No file extension")?
6568
.0;
6669

67-
let tokens = vbare_gen::bare_schema(
68-
&path,
69-
vbare_gen::Config {
70-
use_hashable_map: config.vbare.use_hashable_map,
71-
},
72-
);
70+
let tokens = vbare_gen::bare_schema(&path, config.vbare);
7371
let ast = syn::parse2(tokens)?;
7472
let content = prettyplease::unparse(&ast);
7573

rust/vbare-gen/src/lib.rs

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

9595
mod 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+
97126
fn 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 {
121151
struct SchemaGenerator {
122152
global_output: Vec<TokenStream>,
123153
user_type_registry: BTreeMap<String, AnyType>,
154+
config: Config,
124155
}
125156

126157
impl 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

Comments
 (0)