1717//! Parsing of decl_storage input.
1818
1919use srml_support_procedural_tools:: { ToTokens , Parse , syn_ext as ext} ;
20- use syn:: { Ident , Token } ;
20+ use syn:: { Ident , Token , spanned :: Spanned } ;
2121
2222mod keyword {
2323 syn:: custom_keyword!( hiddencrate) ;
@@ -265,7 +265,6 @@ fn get_module_instance(
265265
266266pub fn parse ( input : syn:: parse:: ParseStream ) -> syn:: Result < super :: DeclStorageDef > {
267267 use syn:: parse:: Parse ;
268- use syn:: spanned:: Spanned ;
269268
270269 let def = StorageDefinition :: parse ( input) ?;
271270
@@ -303,9 +302,31 @@ pub fn parse(input: syn::parse::ParseStream) -> syn::Result<super::DeclStorageDe
303302 }
304303 }
305304
306- let mut storage_lines = vec ! [ ] ;
305+ let storage_lines = parse_storage_line_defs ( def . content . content . inner . into_iter ( ) ) ? ;
307306
308- for line in def. content . content . inner . into_iter ( ) {
307+ Ok ( super :: DeclStorageDef {
308+ hidden_crate : def. hidden_crate . inner . map ( |i| i. ident . content ) ,
309+ visibility : def. visibility ,
310+ module_name : def. module_ident ,
311+ store_trait : def. ident ,
312+ module_runtime_generic : def. mod_param_generic ,
313+ module_runtime_trait : def. mod_param_bound ,
314+ where_clause : def. where_clause ,
315+ crate_name : def. crate_ident ,
316+ module_instance,
317+ extra_genesis_build,
318+ extra_genesis_config_lines,
319+ storage_lines,
320+ } )
321+ }
322+
323+ /// Parse the `DeclStorageLine` into `StorageLineDef`.
324+ fn parse_storage_line_defs (
325+ defs : impl Iterator < Item = DeclStorageLine > ,
326+ ) -> syn:: Result < Vec < super :: StorageLineDef > > {
327+ let mut storage_lines = Vec :: < super :: StorageLineDef > :: new ( ) ;
328+
329+ for line in defs {
309330 let getter = line. getter . inner . map ( |o| o. getfn . content . ident ) ;
310331 let config = if let Some ( config) = line. config . inner {
311332 if let Some ( ident) = config. expr . content {
@@ -315,14 +336,28 @@ pub fn parse(input: syn::parse::ParseStream) -> syn::Result<super::DeclStorageDe
315336 } else {
316337 return Err ( syn:: Error :: new (
317338 config. span ( ) ,
318- "Invalid storage definiton, couldn't find config identifier: storage must either have a get \
319- identifier `get(fn ident)` or a defined config identifier `config(ident)`"
339+ "Invalid storage definition, couldn't find config identifier: storage must \
340+ either have a get identifier `get(fn ident)` or a defined config identifier \
341+ `config(ident)`",
320342 ) )
321343 }
322344 } else {
323345 None
324346 } ;
325347
348+ if let Some ( ref config) = config {
349+ storage_lines. iter ( ) . filter_map ( |sl| sl. config . as_ref ( ) ) . try_for_each ( |other_config| {
350+ if other_config == config {
351+ Err ( syn:: Error :: new (
352+ config. span ( ) ,
353+ "`config()`/`get()` with the same name already defined." ,
354+ ) )
355+ } else {
356+ Ok ( ( ) )
357+ }
358+ } ) ?;
359+ }
360+
326361 let storage_type = match line. storage_type {
327362 DeclStorageType :: Map ( map) => super :: StorageLineTypeDef :: Map (
328363 super :: MapDef {
@@ -365,18 +400,5 @@ pub fn parse(input: syn::parse::ParseStream) -> syn::Result<super::DeclStorageDe
365400 } )
366401 }
367402
368- Ok ( super :: DeclStorageDef {
369- hidden_crate : def. hidden_crate . inner . map ( |i| i. ident . content ) ,
370- visibility : def. visibility ,
371- module_name : def. module_ident ,
372- store_trait : def. ident ,
373- module_runtime_generic : def. mod_param_generic ,
374- module_runtime_trait : def. mod_param_bound ,
375- where_clause : def. where_clause ,
376- crate_name : def. crate_ident ,
377- module_instance,
378- extra_genesis_build,
379- extra_genesis_config_lines,
380- storage_lines,
381- } )
403+ Ok ( storage_lines)
382404}
0 commit comments