This is an automated email from the ASF dual-hosted git repository.

wongoo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo-go-hessian2.git


The following commit(s) were added to refs/heads/master by this push:
     new 0b16449  add a tool for generate hessian2 java enum define golang code 
(#304)
0b16449 is described below

commit 0b164495efd95d09fe7b18f6de93c607499c45c6
Author: MarsMay <[email protected]>
AuthorDate: Thu Dec 30 08:42:32 2021 +0800

    add a tool for generate hessian2 java enum define golang code (#304)
    
    * add a tool for generate hessian2 java enum define golang code
---
 README.md                   |   6 ++
 tools/gen-go-enum/README.md |  94 +++++++++++++++++
 tools/gen-go-enum/main.go   | 244 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 344 insertions(+)

diff --git a/README.md b/README.md
index 0f152c2..987027b 100644
--- a/README.md
+++ b/README.md
@@ -367,3 +367,9 @@ type Dog struct {
        *Animal
 }
 ```
+
+## Tools
+
+###  tools/gen-go-enum
+
+A tool for generate hessian2 java enum define golang code. Read more 
[details](tools/gen-go-enum/README.md).
diff --git a/tools/gen-go-enum/README.md b/tools/gen-go-enum/README.md
new file mode 100644
index 0000000..a13a2c9
--- /dev/null
+++ b/tools/gen-go-enum/README.md
@@ -0,0 +1,94 @@
+# gen-go-enum
+
+A tool for generate hessian2 java enum define golang code.
+
+```sh
+go build -o gen-go-enum tools/gen-go-enum/main.go
+```
+
+For example, run command `gen-go-enum -c com.test.enums.TestColorEnum -v RED 
-v BLUE -v YELLOW` will create a golang code file like this.
+
+```go
+package enum
+
+import (
+       "strconv"
+)
+
+import (
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+const (
+       TestColorEnumRed TestColorEnum = iota
+       TestColorEnumBlue
+       TestColorEnumYellow
+)
+
+var _TestColorEnumValues = map[TestColorEnum]string{
+       TestColorEnumRed: "RED",
+       TestColorEnumBlue: "BLUE",
+       TestColorEnumYellow: "YELLOW",
+}
+
+var _TestColorEnumEntities = map[string]TestColorEnum{
+       "RED": TestColorEnumRed,
+       "BLUE": TestColorEnumBlue,
+       "YELLOW": TestColorEnumYellow,
+}
+
+type TestColorEnum hessian.JavaEnum
+
+func (e TestColorEnum) JavaClassName() string {
+       return "com.test.enums.TestColorEnum"
+}
+
+func (e TestColorEnum) String() string {
+       if v, ok := _TestColorEnumValues[e]; ok {
+               return v
+       }
+
+       return strconv.Itoa(int(e))
+}
+
+func (e TestColorEnum) EnumValue(s string) hessian.JavaEnum {
+       if v, ok := _TestColorEnumEntities[s]; ok {
+               return hessian.JavaEnum(v)
+       }
+
+       return hessian.InvalidJavaEnum
+}
+
+func NewTestColorEnum(s string) TestColorEnum {
+       if v, ok := _TestColorEnumEntities[s]; ok {
+               return v
+       }
+
+       return TestColorEnum(hessian.InvalidJavaEnum)
+}
+
+func init() {
+       for v := range _TestColorEnumValues {
+               hessian.RegisterJavaEnum(v)
+       }
+}
+```
+
+You can specify more options, like the usage.
+
+```sh
+gen-go-enum can generate golang code for hessian2 java enum.
+
+Usage: gen-go-enum -c java_classname [-p golang_package_name] [-e 
golang_enum_name] -v java_enum_value [-v java_enum_value] [-o target_file]
+
+Options
+  -c   java class name (eg: com.test.enums.TestEnum)
+  -p   golang package name, use 'enum' when not specified (eg: test_enum)
+  -e   golang enum type name, use java class name when not specified (eg: 
TestEnum)
+  -v   java enum values, can specify multiple (eg: -v TEST1 -v TEST2 -v TEST3)
+  -o   golang code file path, stored in the current directory when not 
specified
+
+Example
+  gen-go-enum -c com.test.enums.TestColorEnum -v RED -v BLUE -v YELLOW
+  gen-go-enum -c com.test.enums.TestColorEnum -p test_enums -e ColorEnum -v 
RED -v BLUE -v YELLOW -o ./color_enum.go
+```
\ No newline at end of file
diff --git a/tools/gen-go-enum/main.go b/tools/gen-go-enum/main.go
new file mode 100644
index 0000000..1082bbe
--- /dev/null
+++ b/tools/gen-go-enum/main.go
@@ -0,0 +1,244 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package main
+
+import (
+       "flag"
+       "fmt"
+       "html/template"
+       "log"
+       "os"
+       "strings"
+)
+
+type Strings []string
+
+func (t *Strings) String() string {
+       return fmt.Sprint(*t)
+}
+
+func (t *Strings) Set(value string) error {
+       *t = append(*t, value)
+       return nil
+}
+
+type viewData struct {
+       ClassName   string
+       PackageName string
+       EnumName    string
+       EnumValues  []string
+}
+
+func snakeCase(name string) string {
+       if name == "" {
+               return ""
+       }
+
+       var s string
+
+       for k, v := range []rune(name) {
+               if v >= 'A' && v <= 'Z' {
+                       if k > 0 {
+                               s += "_"
+                       }
+
+                       v += 32
+               }
+
+               s += string(v)
+       }
+
+       return s
+}
+
+func pascalCase(name string) string {
+       if name == "" {
+               return ""
+       }
+
+       var s string
+
+       for _, v := range strings.Split(name, "_") {
+               runes := []rune(v)
+
+               for k, vv := range runes {
+                       if k == 0 {
+                               if vv >= 'a' && vv <= 'z' {
+                                       vv -= 32
+                               }
+                       } else if vv >= 'A' && vv <= 'Z' {
+                               vv += 32
+                       }
+
+                       s += string(vv)
+               }
+       }
+
+       return s
+}
+
+const (
+       usage = `gen-go-enum can generate golang code for hessian2 java enum.
+
+Usage: gen-go-enum -c java_classname [-p golang_package_name] [-e 
golang_enum_name] -v java_enum_value [-v java_enum_value] [-o target_file]
+
+Options
+  -c   java class name (eg: com.test.enums.TestEnum)
+  -p   golang package name, use 'enum' when not specified (eg: test_enums)
+  -e   golang enum type name, use java class name when not specified (eg: 
TestEnum)
+  -v   java enum values, can specify multiple (eg: -v TEST1 -v TEST2 -v TEST3)
+  -o   golang code file path, stored in the current directory when not 
specified
+
+Example
+  gen-go-enum -c com.test.enums.TestColorEnum -v RED -v BLUE -v YELLOW
+  gen-go-enum -c com.test.enums.TestColorEnum -p test_enums -e ColorEnum -v 
RED -v BLUE -v YELLOW -o ./color_enum.go
+`
+
+       enumTempl = `package {{.PackageName}}
+
+import (
+       "strconv"
+)
+
+import (
+       hessian "github.com/apache/dubbo-go-hessian2"
+)
+
+const (
+{{- range $index, $value := .EnumValues }}
+       {{$.EnumName}}{{ pascalCase $value}}{{ if eq $index 0 }} {{$.EnumName}} 
= iota{{ end }}
+{{- end }}
+)
+
+var _{{.EnumName}}Values = map[{{.EnumName}}]string{
+{{- range $index, $value := .EnumValues }}
+       {{$.EnumName}}{{ pascalCase $value}}: "{{$value}}",
+{{- end }}
+}
+
+var _{{.EnumName}}Entities = map[string]{{.EnumName}}{
+{{- range $index, $value := .EnumValues }}
+       "{{$value}}": {{$.EnumName}}{{ pascalCase $value}},
+{{- end }}
+}
+
+type {{.EnumName}} hessian.JavaEnum
+
+func (e {{.EnumName}}) JavaClassName() string {
+       return "{{.ClassName}}"
+}
+
+func (e {{.EnumName}}) String() string {
+       if v, ok := _{{.EnumName}}Values[e]; ok {
+               return v
+       }
+
+       return strconv.Itoa(int(e))
+}
+
+func (e {{.EnumName}}) EnumValue(s string) hessian.JavaEnum {
+       if v, ok := _{{.EnumName}}Entities[s]; ok {
+               return hessian.JavaEnum(v)
+       }
+
+       return hessian.InvalidJavaEnum
+}
+
+func New{{.EnumName}}(s string) {{.EnumName}} {
+       if v, ok := _{{.EnumName}}Entities[s]; ok {
+               return v
+       }
+
+       return {{.EnumName}}(hessian.InvalidJavaEnum)
+}
+
+func init() {
+       for v := range _{{.EnumName}}Values {
+               hessian.RegisterJavaEnum(v)
+       }
+}`
+)
+
+var (
+       className   string
+       packageName string
+       enumName    string
+       enumValues  Strings
+       targetFile  string
+)
+
+func init() {
+       flag.StringVar(&className, "c", "", "")
+       flag.StringVar(&packageName, "p", "enum", "")
+       flag.StringVar(&enumName, "e", "", "")
+       flag.Var(&enumValues, "v", "")
+       flag.StringVar(&targetFile, "o", "", "")
+
+       flag.Usage = func() {
+               fmt.Print(usage)
+       }
+}
+
+func main() {
+       flag.Parse()
+
+       if className == "" || len(enumValues) == 0 {
+               flag.Usage()
+               return
+       }
+
+       if packageName == "" {
+               packageName = "enum"
+       }
+
+       if enumName == "" {
+               classItems := strings.Split(className, ".")
+               enumName = classItems[len(classItems)-1]
+       }
+
+       if targetFile == "" {
+               targetFile = snakeCase(enumName) + ".go"
+       }
+
+       tmpl, err := template.New("enum").Funcs(template.FuncMap{"pascalCase": 
pascalCase}).Parse(enumTempl)
+
+       if err != nil {
+               log.Fatalln("Error: can't parse code template!!!", err)
+       }
+
+       fd, err := os.Create(targetFile)
+
+       if err != nil {
+               log.Fatalln("Error: can't open target file!!!", err)
+       }
+
+       defer func() { _ = fd.Close() }()
+
+       err = tmpl.Execute(fd, &viewData{
+               ClassName:   className,
+               PackageName: packageName,
+               EnumName:    enumName,
+               EnumValues:  enumValues,
+       })
+
+       if err != nil {
+               log.Fatalln("Error: can't write target file!!!", err)
+       }
+
+       fmt.Printf("Create file '%s'!\n", targetFile)
+}

Reply via email to