@@ -76,6 +76,38 @@ func BuildImplementationRust(component ComponentDefinition, outputFolder string,
76
76
return err
77
77
}
78
78
79
+ IntfWrapperFileName := BaseName + "_interface_wrapper.rs"
80
+ IntfWrapperFilePath := path .Join (outputFolder , IntfWrapperFileName )
81
+ modfiles = append (modfiles , IntfWrapperFilePath )
82
+ log .Printf ("Creating \" %s\" " , IntfWrapperFilePath )
83
+ IntfWrapperRSFile , err := CreateLanguageFile (IntfWrapperFilePath , indentString )
84
+ if err != nil {
85
+ return err
86
+ }
87
+ IntfWrapperRSFile .WriteCLicenseHeader (component ,
88
+ fmt .Sprintf ("This is an autogenerated Rust implementation file in order to allow easy\n development of %s. The functions in this file need to be implemented. It needs to be generated only once." , LibraryName ),
89
+ true )
90
+ err = buildRustWrapper (component , IntfWrapperRSFile , InterfaceMod )
91
+ if err != nil {
92
+ return err
93
+ }
94
+
95
+ IntfHandleFileName := BaseName + "_interface_handle.rs"
96
+ IntfHandleFilePath := path .Join (outputFolder , IntfHandleFileName )
97
+ modfiles = append (modfiles , IntfHandleFilePath )
98
+ log .Printf ("Creating \" %s\" " , IntfHandleFilePath )
99
+ IntfHandleRSFile , err := CreateLanguageFile (IntfHandleFilePath , indentString )
100
+ if err != nil {
101
+ return err
102
+ }
103
+ IntfHandleRSFile .WriteCLicenseHeader (component ,
104
+ fmt .Sprintf ("This is an autogenerated Rust implementation file in order to allow easy\n development of %s. The functions in this file need to be implemented. It needs to be generated only once." , LibraryName ),
105
+ true )
106
+ err = buildRustHandle (component , IntfHandleRSFile , InterfaceMod )
107
+ if err != nil {
108
+ return err
109
+ }
110
+
79
111
IntfWrapperStubName := path .Join (stubOutputFolder , BaseName + stubIdentifier + ".rs" )
80
112
modfiles = append (modfiles , IntfWrapperStubName )
81
113
if forceRebuild || ! FileExists (IntfWrapperStubName ) {
@@ -344,7 +376,7 @@ func buildRustGlobalStubFile(component ComponentDefinition, w LanguageWriter, In
344
376
w .Writeln ("use %s::*;" , InterfaceMod )
345
377
w .Writeln ("" )
346
378
w .Writeln ("// Wrapper struct to implement the wrapper trait for global methods" )
347
- w .Writeln ("struct CWrapper;" )
379
+ w .Writeln ("pub struct CWrapper;" )
348
380
w .Writeln ("" )
349
381
w .Writeln ("impl Wrapper for CWrapper {" )
350
382
w .Writeln ("" )
@@ -474,3 +506,162 @@ func buildRustStubFile(component ComponentDefinition, class ComponentDefinitionC
474
506
w .Writeln ("" )
475
507
return nil
476
508
}
509
+
510
+ func buildRustWrapper (component ComponentDefinition , w LanguageWriter , InterfaceMod string ) error {
511
+ // Imports
512
+ ModName := strings .ToLower (component .NameSpace )
513
+ w .Writeln ("" )
514
+ w .Writeln ("// Calls from the C-Interface to the Rust traits via the CWrapper" )
515
+ w .Writeln ("// These are the symbols exposed in the shared object interface" )
516
+ w .Writeln ("" )
517
+ w .Writeln ("use %s::*;" , InterfaceMod )
518
+ w .Writeln ("use %s::CWrapper;" , ModName )
519
+ w .Writeln ("use std::ffi::{c_char, CStr};" )
520
+ w .Writeln ("" )
521
+ cprefix := ModName + "_"
522
+ // Build the global methods
523
+ err := writeGlobalRustWrapper (component , w , cprefix )
524
+ if err != nil {
525
+ return err
526
+ }
527
+ return nil
528
+ }
529
+
530
+ func buildRustHandle (component ComponentDefinition , w LanguageWriter , InterfaceMod string ) error {
531
+ w .Writeln ("" )
532
+ w .Writeln ("// Handle passed through interface define the casting maps needed to extract" )
533
+ w .Writeln ("" )
534
+ w .Writeln ("use %s::*;" , InterfaceMod )
535
+ w .Writeln ("" )
536
+ w .Writeln ("impl HandleImpl {" )
537
+ w .AddIndentationLevel (1 )
538
+ for i := 0 ; i < len (component .Classes ); i ++ {
539
+ class := component .Classes [i ]
540
+ writeRustHandleAs (component , w , class , false )
541
+ writeRustHandleAs (component , w , class , true )
542
+ w .Writeln ("" )
543
+ }
544
+ w .AddIndentationLevel (- 1 )
545
+ w .Writeln ("}" )
546
+ return nil
547
+ }
548
+
549
+ func writeRustHandleAs (component ComponentDefinition , w LanguageWriter , class ComponentDefinitionClass , mut bool ) error {
550
+ //parents, err := getParentList(component, class)
551
+ //if err != nil {
552
+ // return err
553
+ //}
554
+ Name := class .ClassName
555
+ if ! mut {
556
+ w .Writeln ("pub fn as_%s(&self) -> Option<&dyn %s> {" , toSnakeCase (Name ), Name )
557
+ } else {
558
+ w .Writeln ("pub fn as_mut_%s(&mut self) -> Option<&mut dyn %s> {" , toSnakeCase (Name ), Name )
559
+ }
560
+ w .AddIndentationLevel (1 )
561
+ w .Writeln ("None" )
562
+ w .AddIndentationLevel (- 1 )
563
+ w .Writeln ("}" )
564
+ return nil
565
+ }
566
+
567
+ func writeGlobalRustWrapper (component ComponentDefinition , w LanguageWriter , cprefix string ) error {
568
+ methods := component .Global .Methods
569
+ for i := 0 ; i < len (methods ); i ++ {
570
+ method := methods [i ]
571
+ err := writeRustMethodWrapper (method , w , cprefix )
572
+ if err != nil {
573
+ return err
574
+ }
575
+ w .Writeln ("" )
576
+ }
577
+ return nil
578
+ }
579
+
580
+ func writeRustMethodWrapper (method ComponentDefinitionMethod , w LanguageWriter , cprefix string ) error {
581
+ // Build up the parameter strings
582
+ parameterString := ""
583
+ returnName := ""
584
+ for k := 0 ; k < len (method .Params ); k ++ {
585
+ param := method .Params [k ]
586
+ RustParams , err := generateRustParameters (param , true )
587
+ if err != nil {
588
+ return err
589
+ }
590
+ for i := 0 ; i < len (RustParams ); i ++ {
591
+ RustParam := RustParams [i ]
592
+ if parameterString == "" {
593
+ parameterString += fmt .Sprintf ("%s : %s" , RustParam .ParamName , RustParam .ParamType )
594
+ } else {
595
+ parameterString += fmt .Sprintf (", %s : %s" , RustParam .ParamName , RustParam .ParamType )
596
+ }
597
+ }
598
+ }
599
+ w .Writeln ("pub fn %s%s(%s) -> i32 {" , cprefix , strings .ToLower (method .MethodName ), parameterString )
600
+ w .AddIndentationLevel (1 )
601
+ argsString := ""
602
+ for k := 0 ; k < len (method .Params ); k ++ {
603
+ param := method .Params [k ]
604
+ OName , err := writeRustParameterConversionArg (param , w )
605
+ if err != nil {
606
+ return err
607
+ }
608
+ if OName != "" {
609
+ if argsString == "" {
610
+ argsString = OName
611
+ } else {
612
+ argsString += fmt .Sprintf (", %s" , OName )
613
+ }
614
+ }
615
+ }
616
+ if returnName != "" {
617
+ w .Writeln ("let %s = CWrapper::%s(%s);" , returnName , toSnakeCase (method .MethodName ), argsString )
618
+ } else {
619
+ w .Writeln ("CWrapper::%s(%s);" , toSnakeCase (method .MethodName ), argsString )
620
+ }
621
+ w .Writeln ("// All ok" )
622
+ w .Writeln ("0" )
623
+ w .AddIndentationLevel (- 1 )
624
+ w .Writeln ("}" )
625
+ return nil
626
+ }
627
+
628
+ func writeRustParameterConversionArg (param ComponentDefinitionParam , w LanguageWriter ) (string , error ) {
629
+ if param .ParamPass == "return" {
630
+ return "" , nil
631
+ }
632
+ IName := toSnakeCase (param .ParamName )
633
+ OName := "_" + IName
634
+ switch param .ParamType {
635
+ case "uint8" , "uint16" , "uint32" , "uint64" , "int8" , "int16" , "int32" , "int64" , "single" , "double" :
636
+ if param .ParamPass == "in" {
637
+ w .Writeln ("let %s = %s;" , OName , IName )
638
+ } else {
639
+ w .Writeln ("let %s = unsafe {&mut *%s};" , OName , IName )
640
+ }
641
+ case "class" , "optionalclass" :
642
+ if param .ParamPass == "in" {
643
+ HName := "_Handle_" + IName
644
+ w .Writeln ("let %s = unsafe {&*%s};" , HName , IName )
645
+ w .Writeln ("let %s = %s.as_%s().unwrap();" , OName , HName , toSnakeCase (param .ParamClass ))
646
+ } else {
647
+ HName := "_Handle_" + IName
648
+ w .Writeln ("let %s = unsafe {&mut *%s};" , HName , IName )
649
+ w .Writeln ("let %s = %s.as_mut_%s().unwrap();" , OName , HName , toSnakeCase (param .ParamClass ))
650
+ }
651
+ case "string" :
652
+ if param .ParamPass == "in" {
653
+ SName := "_Str_" + IName
654
+ w .Writeln ("let %s = unsafe{ CStr::from_ptr(%s) };" , SName , IName )
655
+ w .Writeln ("let %s = %s.to_str().unwrap();" , OName , SName )
656
+ } else {
657
+ SName := "_String_" + IName
658
+ w .Writeln ("let mut %s = String::new();" , SName )
659
+ w .Writeln ("let %s = &mut %s;" , OName , SName )
660
+ }
661
+ case "bool" , "pointer" , "struct" , "basicarray" , "structarray" :
662
+ //return fmt.Errorf("Conversion of type %s for parameter %s not supported", param.ParamType, IName)
663
+ default :
664
+ return "" , fmt .Errorf ("Conversion of type %s for parameter %s not supported as is unknown" , param .ParamType , IName )
665
+ }
666
+ return OName , nil
667
+ }
0 commit comments