1
1
use crate :: bail;
2
2
use proc_macro2:: TokenStream ;
3
- use quote:: quote;
3
+ use quote:: { format_ident , quote} ;
4
4
use std:: borrow:: Cow ;
5
5
use syn:: { DataEnum , DataStruct , DataUnion , DeriveInput , Lit } ;
6
6
7
+ type Converter = fn ( & str ) -> String ;
8
+
9
+ fn case_converter ( case : & syn:: LitStr ) -> syn:: Result < Converter > {
10
+ macro_rules! define_converter {
11
+ ( match $value: expr => {
12
+ $( $case: pat => $converter: expr, ) *
13
+ } ) => {
14
+ match $value {
15
+ $( $case => |txt: & str | $converter( txt) . to_string( ) , ) *
16
+ _ => return Err ( syn:: Error :: new_spanned( case, "unsupported case style" ) ) ,
17
+ }
18
+ } ;
19
+ }
20
+
21
+ let case = case. value ( ) ;
22
+ let converter = define_converter ! ( match case. as_str( ) => {
23
+ "camelCase" => heck:: AsLowerCamelCase ,
24
+ "snake_case" => heck:: AsSnakeCase ,
25
+ "kebab-case" => heck:: AsKebabCase ,
26
+ "SCREAMING_SNAKE_CASE" => heck:: AsShoutySnakeCase ,
27
+ "SCREAMING-KEBAB-CASE" => heck:: AsShoutyKebabCase ,
28
+ } ) ;
29
+
30
+ Ok ( converter)
31
+ }
32
+
33
+ fn ident_adapter ( converter : Converter ) -> impl Fn ( & syn:: Ident ) -> syn:: Ident {
34
+ let adapter = move |ident : & syn:: Ident | format_ident ! ( "{}" , converter( & ident. to_string( ) ) ) ;
35
+ Box :: new ( adapter)
36
+ }
37
+
7
38
struct SerdeContainerOptions {
8
39
rename_all : Option < syn:: LitStr > ,
9
40
untagged : bool ,
@@ -140,13 +171,20 @@ pub struct ContainerMeta {
140
171
141
172
fn expand_enum ( mut meta : ContainerMeta , input : DataEnum ) -> syn:: Result < TokenStream > {
142
173
let crate_path = & meta. options . crate_path ;
174
+ let converter = ident_adapter (
175
+ meta. serde_options
176
+ . rename_all
177
+ . as_ref ( )
178
+ . map ( case_converter)
179
+ . unwrap_or_else ( || Ok ( |txt : & str | txt. to_string ( ) ) ) ?,
180
+ ) ;
143
181
144
182
let mut cases = Vec :: new ( ) ;
145
183
for variant in input. variants . iter ( ) {
146
184
let value = match variant. fields {
147
185
syn:: Fields :: Named ( ref fields) => {
148
186
let items = fields. named . iter ( ) . map ( |field| {
149
- let name = field. ident . as_ref ( ) . unwrap ( ) ;
187
+ let name = converter ( field. ident . as_ref ( ) . unwrap ( ) ) ;
150
188
let description = normalize_option ( extract_documentation ( & field. attrs ) ?) ;
151
189
let field_ty = & field. ty ;
152
190
@@ -185,7 +223,7 @@ fn expand_enum(mut meta: ContainerMeta, input: DataEnum) -> syn::Result<TokenStr
185
223
syn:: Fields :: Unit => quote ! { #crate_path:: EnumValue :: Unit } ,
186
224
} ;
187
225
188
- let variant_name = & variant. ident ;
226
+ let variant_name = converter ( & variant. ident ) ;
189
227
let description = normalize_option ( extract_documentation ( & variant. attrs ) ?) ;
190
228
191
229
let expanded = quote ! {
@@ -214,7 +252,7 @@ fn expand_enum(mut meta: ContainerMeta, input: DataEnum) -> syn::Result<TokenStr
214
252
impl #impl_generics #crate_path:: Schemaifier for #name #ty_generics #where_clause {
215
253
fn visit_schema( visitor: & mut #crate_path:: SchemaVisitor ) -> #crate_path:: DefinitionReference {
216
254
let node = #crate_path:: Node {
217
- name: std :: any :: type_name :: < Self > ( ) . into( ) ,
255
+ name: stringify! ( #name ) . into( ) ,
218
256
description: #description,
219
257
value: #crate_path:: NodeType :: Enum {
220
258
discriminator: None ,
@@ -231,6 +269,14 @@ fn expand_enum(mut meta: ContainerMeta, input: DataEnum) -> syn::Result<TokenStr
231
269
}
232
270
233
271
fn expand_struct ( mut meta : ContainerMeta , input : DataStruct ) -> syn:: Result < TokenStream > {
272
+ let converter = ident_adapter (
273
+ meta. serde_options
274
+ . rename_all
275
+ . as_ref ( )
276
+ . map ( case_converter)
277
+ . unwrap_or_else ( || Ok ( |txt : & str | txt. to_string ( ) ) ) ?,
278
+ ) ;
279
+
234
280
let name = & meta. name ;
235
281
let description = normalize_option ( meta. description . as_ref ( ) ) ;
236
282
let crate_path = & meta. options . crate_path ;
@@ -249,7 +295,7 @@ fn expand_struct(mut meta: ContainerMeta, input: DataStruct) -> syn::Result<Toke
249
295
let node_ty = match input. fields {
250
296
syn:: Fields :: Named ( named) => {
251
297
let items = named. named . iter ( ) . map ( |field| {
252
- let name = field. ident . as_ref ( ) . unwrap ( ) ;
298
+ let name = converter ( field. ident . as_ref ( ) . unwrap ( ) ) ;
253
299
let description = normalize_option ( extract_documentation ( & field. attrs ) ?) ;
254
300
let field_ty = & field. ty ;
255
301
@@ -297,7 +343,7 @@ fn expand_struct(mut meta: ContainerMeta, input: DataStruct) -> syn::Result<Toke
297
343
298
344
quote ! {
299
345
#crate_path:: Node {
300
- name: std :: any :: type_name :: < Self > ( ) . into( ) ,
346
+ name: stringify! ( #name ) . into( ) ,
301
347
description: #description,
302
348
value: #node_ty,
303
349
}
0 commit comments