@@ -30,10 +30,6 @@ use crate::schema_capnp;
3030use crate :: codegen_types:: { Leaf , RustTypeInfo , RustNodeInfo , TypeParameterTexts , do_branding } ;
3131use self :: FormattedText :: { Indent , Line , Branch , BlankLine } ;
3232
33- fn root_scope ( root_name : String ) -> Vec < String > {
34- vec ! [ "crate" . into( ) , root_name]
35- }
36-
3733pub struct GeneratorContext < ' a > {
3834 pub request : schema_capnp:: code_generator_request:: Reader < ' a > ,
3935 pub node_map : collections:: hash_map:: HashMap < u64 , schema_capnp:: node:: Reader < ' a > > ,
@@ -67,15 +63,19 @@ impl <'a> GeneratorContext<'a> {
6763 path_to_stem_string( importpath) ?. replace( "-" , "_" ) ) ;
6864 populate_scope_map ( & gen. node_map ,
6965 & mut gen. scope_map ,
70- root_scope ( root_name) ,
66+ vec ! [ "crate" . into( ) ] ,
67+ root_name,
68+ NameKind :: Verbatim ,
7169 import. get_id ( ) ) ?;
7270 }
7371
7472 let root_name = path_to_stem_string ( requested_file. get_filename ( ) ?) ?;
7573 let root_mod = format ! ( "{}_capnp" , root_name. replace( "-" , "_" ) ) ;
7674 populate_scope_map ( & gen. node_map ,
7775 & mut gen. scope_map ,
78- root_scope ( root_mod) ,
76+ vec ! [ "crate" . into( ) ] ,
77+ root_mod,
78+ NameKind :: Verbatim ,
7979 id) ?;
8080 }
8181 Ok ( gen)
@@ -229,7 +229,7 @@ const RUST_KEYWORDS : [&'static str; 53] =
229229 "typeof" , "unsafe" , "unsized" , "use" , "virtual" ,
230230 "where" , "while" , "yield" ] ;
231231
232- fn module_name ( camel_case : & str ) -> String {
232+ fn module_name ( camel_case : & str ) -> String {
233233 let mut name = camel_to_snake_case ( camel_case) ;
234234 if RUST_KEYWORDS . contains ( & & * name) {
235235 name. push ( '_' ) ;
@@ -252,31 +252,68 @@ fn get_field_name(field: schema_capnp::field::Reader) -> capnp::Result<&str> {
252252 field. get_name ( )
253253}
254254
255+ enum NameKind {
256+ // convert camel case to snake case, and avoid Rust keywords
257+ Module ,
258+
259+ // don't modify
260+ Verbatim ,
261+ }
262+
263+ fn capnp_name_to_rust_name ( capnp_name : & str , name_kind : NameKind ) -> String {
264+ match name_kind {
265+ NameKind :: Module => module_name ( capnp_name) ,
266+ NameKind :: Verbatim => capnp_name. to_string ( ) ,
267+ }
268+ }
269+
255270fn populate_scope_map ( node_map : & collections:: hash_map:: HashMap < u64 , schema_capnp:: node:: Reader > ,
256271 scope_map : & mut collections:: hash_map:: HashMap < u64 , Vec < String > > ,
257- scope_names : Vec < String > ,
272+ ancestor_scope_names : Vec < String > ,
273+ mut current_node_name : String ,
274+ current_name_kind : NameKind ,
258275 node_id : u64 ) -> :: capnp:: Result < ( ) > {
259-
260- scope_map. insert ( node_id, scope_names. clone ( ) ) ;
261-
262276 // unused nodes in imported files might be omitted from the node map
263277 let node_reader = match node_map. get ( & node_id) { Some ( node) => node, None => return Ok ( ( ) ) , } ;
264278
279+ ' annotations: for annotation in node_reader. get_annotations ( ) ?. iter ( ) {
280+ if annotation. get_id ( ) == NAME_ANNOTATION_ID {
281+ if let schema_capnp:: value:: Text ( t) = annotation. get_value ( ) ?. which ( ) ? {
282+ current_node_name = t?. to_string ( ) ;
283+ break ' annotations;
284+ } else {
285+ return Err ( capnp:: Error :: failed ( format ! ( "expected rust.name annotation value to be of type Text" ) ) ) ;
286+ }
287+ }
288+ }
289+
290+ let mut scope_names = ancestor_scope_names;
291+ scope_names. push ( capnp_name_to_rust_name ( & current_node_name, current_name_kind) ) ;
292+
293+ scope_map. insert ( node_id, scope_names. clone ( ) ) ;
294+
265295 let nested_nodes = node_reader. get_nested_nodes ( ) ?;
266296 for nested_node in nested_nodes. iter ( ) {
267- let mut scope_names = scope_names. clone ( ) ;
268297 let nested_node_id = nested_node. get_id ( ) ;
269298 match node_map. get ( & nested_node_id) {
270299 None => { }
271300 Some ( node_reader) => {
272301 match node_reader. which ( ) {
273302 Ok ( schema_capnp:: node:: Enum ( _enum_reader) ) => {
274- scope_names. push ( nested_node. get_name ( ) ?. to_string ( ) ) ;
275- populate_scope_map ( node_map, scope_map, scope_names, nested_node_id) ?;
303+ populate_scope_map ( node_map,
304+ scope_map,
305+ scope_names. clone ( ) ,
306+ nested_node. get_name ( ) ?. to_string ( ) ,
307+ NameKind :: Verbatim ,
308+ nested_node_id) ?;
276309 }
277310 _ => {
278- scope_names. push ( module_name ( nested_node. get_name ( ) ?) ) ;
279- populate_scope_map ( node_map, scope_map, scope_names, nested_node_id) ?;
311+ populate_scope_map ( node_map,
312+ scope_map,
313+ scope_names. clone ( ) ,
314+ nested_node. get_name ( ) ?. to_string ( ) ,
315+ NameKind :: Module ,
316+ nested_node_id) ?;
280317 }
281318 }
282319 }
@@ -289,10 +326,12 @@ fn populate_scope_map(node_map: &collections::hash_map::HashMap<u64, schema_capn
289326 for field in fields. iter ( ) {
290327 match field. which ( ) {
291328 Ok ( schema_capnp:: field:: Group ( group) ) => {
292- let name = module_name ( get_field_name ( field) ?) ;
293- let mut scope_names = scope_names. clone ( ) ;
294- scope_names. push ( name) ;
295- populate_scope_map ( node_map, scope_map, scope_names, group. get_type_id ( ) ) ?;
329+ populate_scope_map ( node_map,
330+ scope_map,
331+ scope_names. clone ( ) ,
332+ get_field_name ( field) ?. to_string ( ) ,
333+ NameKind :: Module ,
334+ group. get_type_id ( ) ) ?;
296335 }
297336 _ => { }
298337 }
0 commit comments