diff --git a/edn/malli.go b/edn/malli.go new file mode 100644 index 000000000..b324c2842 --- /dev/null +++ b/edn/malli.go @@ -0,0 +1,77 @@ +package edn + +import ( + "fmt" + "reflect" + "regexp" + "strings" +) + +var primitiveGoTypeToMalli = map[string]string{ + "bool": ":boolean", + "string": ":string", + "float64": ":double", + "int": ":int", + "int32": ":int", + "uint8": ":int", + "uint32": ":int", + "uint64": ":int", +} + +func convertCamelToKebab(input string) string { + re := regexp.MustCompile("([a-z])([A-Z])") + kebab := re.ReplaceAllString(input, "${1}-${2}") + return strings.ToLower(kebab) +} + +func handleType(fieldType reflect.Type) any { + kind := fieldType.Kind() + + if kind == reflect.Interface { + return ":any" + } + + if kind == reflect.Struct { + return ConvertStructToMalli(fieldType) + } + + if kind == reflect.Slice { + elemType := fieldType.Elem() + // Handle the type that the pointer points to. + if elemType.Kind() == reflect.Ptr { + return []any{handleType(elemType.Elem())} + } + return []any{handleType(elemType)} + } + + return primitiveGoTypeToMalli[kind.String()] +} + +func ConvertStructToMalli(typ reflect.Type) map[string]any { + if typ.Kind() == reflect.Ptr { + typ = typ.Elem() // Dereference if it's a pointer to a struct type + } + + if typ.Kind() != reflect.Struct { + panic("ConvertStructToMalli expects a struct type or pointer to a struct type") + } + + malliSchema := make(map[string]any) + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + fmt.Println(field) + + if !field.IsExported() { + continue + } + + kebabFieldName := convertCamelToKebab(field.Name) + + if field.Type.Kind() == reflect.Ptr { + malliSchema[kebabFieldName] = handleType(field.Type.Elem()) + } else { + malliSchema[kebabFieldName] = handleType(field.Type) + } + } + return malliSchema +} diff --git a/edn/malli_test.go b/edn/malli_test.go new file mode 100644 index 000000000..63b0e3fba --- /dev/null +++ b/edn/malli_test.go @@ -0,0 +1,19 @@ +package edn + +import ( + "encoding/json" + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/require" + + common "github.com/status-im/status-go/protocol/common" +) + +func TestConvertStructToMalli(t *testing.T) { + malliRepresentation := ConvertStructToMalli(reflect.TypeOf(common.Message{})) + bytes, err := json.MarshalIndent(malliRepresentation, "", " ") + require.NoError(t, err) + fmt.Println(string(bytes)) +}