This repository has been archived by the owner on Mar 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
avro.go
94 lines (81 loc) · 1.84 KB
/
avro.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package structstoschema
import (
"errors"
"reflect"
)
const (
AvroTypeRecord = "record"
AvroTypeString = "string"
AvroTypeBool = "boolean"
AvroTypeInt32 = "int"
AvroTypeInt64 = "long"
AvroTypeFloat = "float"
AvroTypeDouble = "double"
)
type Element struct {
Name string
Type string
Children []Element
}
func ParseAvro(in any) (string, error) {
root := Element{}
t := reflect.TypeOf(in)
if t.Kind() != reflect.Struct {
return "", errors.New("Invalid type")
}
root.Name = t.Name()
root.Type = AvroTypeRecord
root.Children = ParseAvroElements(t)
return root.toAvsc(), nil
}
func (e *Element) toAvsc() string {
s := ""
if len(e.Children) == 0 {
s = `{"name":"` + e.Name + `","type":"` + e.Type + `"}`
} else {
fields := ""
for _, child := range e.Children {
fields += "," + child.toAvsc()
}
fields = fields[1:]
s = `{"name":"` + e.Name + `","type":"` + e.Type + `","fields":[` + fields + `]}`
}
return s
}
func ParseAvroElements(t reflect.Type) []Element {
elements := []Element{}
for i := 0; i < t.NumField(); i++ {
field := t.Field(i)
if field.Type.Kind() != reflect.Struct {
elements = append(elements, Element{
Name: field.Tag.Get("avro"),
Type: castTypeToAvro(field.Type.Kind()),
})
} else {
elements = append(elements, Element{
Name: field.Tag.Get("avro"),
Type: AvroTypeRecord,
Children: ParseAvroElements(field.Type),
})
}
}
return elements
}
func castTypeToAvro(k reflect.Kind) string {
switch k {
case reflect.Bool:
return AvroTypeBool
case reflect.Float32:
return AvroTypeFloat
case reflect.Float64:
return AvroTypeDouble
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
return AvroTypeInt32
case reflect.Int64:
return AvroTypeInt64
case reflect.String:
return AvroTypeString
default:
panic(errors.New("Invalid type"))
}
}