2023-06-08 16:59:08 +02:00
|
|
|
package jsvm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
"unicode"
|
|
|
|
|
|
|
|
"github.com/dop251/goja"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
_ goja.FieldNameMapper = (*FieldMapper)(nil)
|
|
|
|
)
|
|
|
|
|
|
|
|
// FieldMapper provides custom mapping between Go and JavaScript property names.
|
|
|
|
//
|
|
|
|
// It is similar to the builtin "uncapFieldNameMapper" but also converts
|
|
|
|
// all uppercase identifiers to their lowercase equivalent (eg. "GET" -> "get").
|
|
|
|
type FieldMapper struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
// FieldName implements the [FieldNameMapper.FieldName] interface method.
|
|
|
|
func (u FieldMapper) FieldName(_ reflect.Type, f reflect.StructField) string {
|
|
|
|
return convertGoToJSName(f.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MethodName implements the [FieldNameMapper.MethodName] interface method.
|
|
|
|
func (u FieldMapper) MethodName(_ reflect.Type, m reflect.Method) string {
|
|
|
|
return convertGoToJSName(m.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func convertGoToJSName(name string) string {
|
2023-06-14 12:14:30 +02:00
|
|
|
startUppercase := make([]rune, 0, len(name))
|
|
|
|
|
2023-06-08 16:59:08 +02:00
|
|
|
for _, c := range name {
|
2023-06-14 12:14:30 +02:00
|
|
|
if c != '_' && !unicode.IsUpper(c) && !unicode.IsDigit(c) {
|
2023-06-08 16:59:08 +02:00
|
|
|
break
|
|
|
|
}
|
2023-06-14 12:14:30 +02:00
|
|
|
|
|
|
|
startUppercase = append(startUppercase, c)
|
2023-06-08 16:59:08 +02:00
|
|
|
}
|
|
|
|
|
2023-06-14 12:14:30 +02:00
|
|
|
totalStartUppercase := len(startUppercase)
|
|
|
|
|
|
|
|
// all uppercase eg. "JSON" -> "json"
|
|
|
|
if len(name) == totalStartUppercase {
|
2023-06-08 16:59:08 +02:00
|
|
|
return strings.ToLower(name)
|
|
|
|
}
|
|
|
|
|
2023-06-14 12:14:30 +02:00
|
|
|
// eg. "JSONField" -> "jsonField"
|
|
|
|
if totalStartUppercase > 1 {
|
|
|
|
return strings.ToLower(name[0:totalStartUppercase-1]) + name[totalStartUppercase-1:]
|
|
|
|
}
|
|
|
|
|
2023-06-08 16:59:08 +02:00
|
|
|
// eg. "GetField" -> "getField"
|
2023-06-14 12:14:30 +02:00
|
|
|
if totalStartUppercase == 1 {
|
|
|
|
return strings.ToLower(name[0:1]) + name[1:]
|
|
|
|
}
|
|
|
|
|
|
|
|
return name
|
2023-06-08 16:59:08 +02:00
|
|
|
}
|