1package gen
2
3import (
4	"bytes"
5	"fmt"
6)
7
8func cleanName(s string) string {
9	if s == "type" {
10		s = "typeName"
11	} else if s == "string" {
12		s = "stringName"
13	}
14	return s
15}
16
17func isSlice(k string) bool {
18	return len(k) > 1 && k[0] == '[' && k[1] == ']'
19}
20
21func deSlice(k string) string {
22	if k[0] == '[' && k[1] == ']' {
23		return k[2:]
24	}
25	return k
26}
27
28func isPtrType(k string) bool {
29	return k[0] == '*'
30}
31
32func deref(k string) string {
33	if k[0] == '*' {
34		return k[1:]
35	}
36	return k
37}
38
39func isIRIType(k string) bool {
40	return k == "*url.URL"
41}
42
43func deserializeCode(b *bytes.Buffer, parseCode, varName, typeName, field string, slice, derefAppend bool) {
44	if slice {
45		sliceDeserializeCode(b, parseCode, varName, typeName, field, derefAppend)
46	} else {
47		singleDeserializeCode(b, parseCode, varName, typeName, field)
48	}
49}
50
51func sliceDeserializeCode(b *bytes.Buffer, parseCode, mapName, typeName, field string, deref bool) {
52	b.WriteString(fmt.Sprintf("if k == \"%s\" {\n", mapName))
53	b.WriteString("if tmpSlice, ok := v.([]interface{}); ok {\n")
54	b.WriteString(fmt.Sprintf("for _, tmpElem := range tmpSlice {\n"))
55	b.WriteString(fmt.Sprintf("if v, ok := tmpElem.(%s); ok {\n", typeName))
56	b.WriteString(parseCode)
57	b.WriteString("if err != nil {\nreturn err\n}\n")
58	if deref {
59		b.WriteString(fmt.Sprintf("t.%s = append(t.%s, *tmp)\n", field, field))
60	} else {
61		b.WriteString(fmt.Sprintf("t.%s = append(t.%s, tmp)\n", field, field))
62	}
63	b.WriteString("handled = true\n")
64	b.WriteString("}\n")
65	b.WriteString("}\n")
66	b.WriteString(fmt.Sprintf("} else if v, ok := v.(%s); ok {\n", typeName))
67	b.WriteString(parseCode)
68	b.WriteString("if err != nil {\nreturn err\n}\n")
69	if deref {
70		b.WriteString(fmt.Sprintf("t.%s = append(t.%s, *tmp)\n", field, field))
71	} else {
72		b.WriteString(fmt.Sprintf("t.%s = append(t.%s, tmp)\n", field, field))
73	}
74	b.WriteString("handled = true\n")
75	b.WriteString("}\n")
76	b.WriteString("}\n")
77}
78
79func singleDeserializeCode(b *bytes.Buffer, parseCode, mapName, typeName, field string) {
80	b.WriteString(fmt.Sprintf("if k == \"%s\" {\n", mapName))
81	b.WriteString(fmt.Sprintf("if v, ok := v.(%s); ok {\n", typeName))
82	b.WriteString(parseCode)
83	b.WriteString("if err != nil {\nreturn err\n}\n")
84	b.WriteString(fmt.Sprintf("t.%s = tmp\n", field))
85	b.WriteString("handled = true\n")
86	b.WriteString("}\n")
87	b.WriteString("}\n")
88}
89
90func serializeCode(b *bytes.Buffer, sCode, mapName, field string, slice bool) {
91	if slice {
92		sliceSerializeCode(b, sCode, mapName, field)
93	} else {
94		singleSerializeCode(b, sCode, mapName, field)
95	}
96}
97
98func sliceSerializeCode(b *bytes.Buffer, serializeCode, mapName, field string) {
99	b.WriteString(fmt.Sprintf("var %sTemp []interface{}\n", mapName))
100	b.WriteString(fmt.Sprintf("for _, v := range t.%s {\n", field))
101	b.WriteString(serializeCode)
102	b.WriteString(fmt.Sprintf("%sTemp = append(%sTemp, tmp)\n", mapName, mapName))
103	b.WriteString("}\n")
104	b.WriteString(fmt.Sprintf("if %sTemp != nil {\n", mapName))
105	b.WriteString(fmt.Sprintf("if len(%sTemp) == 1 {\n", mapName))
106	b.WriteString(fmt.Sprintf("m[\"%s\"] = %sTemp[0]\n", mapName, mapName))
107	b.WriteString("} else {\n")
108	b.WriteString(fmt.Sprintf("m[\"%s\"] = %sTemp\n", mapName, mapName))
109	b.WriteString("}\n")
110	b.WriteString("}\n")
111}
112
113func singleSerializeCode(b *bytes.Buffer, serializeCode, mapName, field string) {
114	b.WriteString(fmt.Sprintf("if t.%s != nil {\n", field))
115	b.WriteString(fmt.Sprintf("%sSerializeFunc := func() (interface{}, error) {\n", mapName))
116	b.WriteString(fmt.Sprintf("v := t.%s\n", field))
117	b.WriteString(serializeCode)
118	b.WriteString("return tmp, nil\n")
119	b.WriteString("}\n")
120	b.WriteString(fmt.Sprintf("%sResult, err := %sSerializeFunc()\n", mapName, mapName))
121	b.WriteString("if err == nil {\n")
122	b.WriteString(fmt.Sprintf("m[\"%s\"] = %sResult\n", mapName, mapName))
123	b.WriteString("} else {\n")
124	b.WriteString("return m, err\n")
125	b.WriteString("}\n")
126	b.WriteString("}\n")
127}
128