[dart-gen] Support Null-safe and omitempty json tag (#3134)
This commit is contained in:
@@ -42,15 +42,29 @@ class {{.Name}} {
|
|||||||
{{range .Members}} required this.{{lowCamelCase .Name}},
|
{{range .Members}} required this.{{lowCamelCase .Name}},
|
||||||
{{end}}}{{end}});
|
{{end}}}{{end}});
|
||||||
factory {{.Name}}.fromJson(Map<String,dynamic> m) {
|
factory {{.Name}}.fromJson(Map<String,dynamic> m) {
|
||||||
return {{.Name}}({{range .Members}}
|
return {{.Name}}(
|
||||||
{{lowCamelCase .Name}}: {{if isDirectType .Type.Name}}m['{{getPropertyFromMember .}}']
|
{{range .Members}}
|
||||||
{{else if isClassListType .Type.Name}}(m['{{getPropertyFromMember .}}'] as List<dynamic>).map((i) => {{getCoreType .Type.Name}}.fromJson(i)).toList()
|
{{lowCamelCase .Name}}: {{appendNullCoalescing .}}
|
||||||
{{else}}{{.Type.Name}}.fromJson(m['{{getPropertyFromMember .}}']){{end}},{{end}}
|
{{if isDirectType .Type.Name}}
|
||||||
|
m['{{getPropertyFromMember .}}'] {{appendDefaultEmptyValue .Type.Name}}
|
||||||
|
{{else if isClassListType .Type.Name}}
|
||||||
|
((m['{{getPropertyFromMember .}}'] {{appendDefaultEmptyValue .Type.Name}}) as List<dynamic>).map((i) => {{getCoreType .Type.Name}}.fromJson(i)).toList()
|
||||||
|
{{else}}
|
||||||
|
{{.Type.Name}}.fromJson(m['{{getPropertyFromMember .}}']){{end}}
|
||||||
|
,{{end}}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Map<String,dynamic> toJson() {
|
Map<String,dynamic> toJson() {
|
||||||
return { {{range .Members}}
|
return { {{range .Members}}
|
||||||
'{{getPropertyFromMember .}}': {{if isDirectType .Type.Name}}{{lowCamelCase .Name}}{{else if isClassListType .Type.Name}}{{lowCamelCase .Name}}.map((i) => i.toJson()){{else}}{{lowCamelCase .Name}}.toJson(){{end}},{{end}}
|
'{{getPropertyFromMember .}}':
|
||||||
|
{{if isDirectType .Type.Name}}
|
||||||
|
{{lowCamelCase .Name}}
|
||||||
|
{{else if isClassListType .Type.Name}}
|
||||||
|
{{lowCamelCase .Name}}{{if isNullableType .Type.Name}}?{{end}}.map((i) => i.toJson())
|
||||||
|
{{else}}
|
||||||
|
{{lowCamelCase .Name}}{{if isNullableType .Type.Name}}?{{end}}.toJson()
|
||||||
|
{{end}}
|
||||||
|
,{{end}}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,52 @@ func isClassListType(s string) bool {
|
|||||||
return strings.HasPrefix(s, "List<") && !isAtomicType(getCoreType(s))
|
return strings.HasPrefix(s, "List<") && !isAtomicType(getCoreType(s))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isMapType(s string) bool {
|
||||||
|
return strings.HasPrefix(s, "Map<")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only interface types are nullable
|
||||||
|
func isNullableType(s string) bool {
|
||||||
|
return strings.HasSuffix(s, "?")
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendNullCoalescing(member spec.Member) string {
|
||||||
|
if isNullableType(member.Type.Name()) {
|
||||||
|
return "m['" + getPropertyFromMember(member) + "'] == null ? null : "
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// To be compatible with omitempty tags in Golang
|
||||||
|
// Only set default value for non-nullable types
|
||||||
|
func appendDefaultEmptyValue(s string) string {
|
||||||
|
if isNullableType(s) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAtomicType(s) {
|
||||||
|
switch s {
|
||||||
|
case "String":
|
||||||
|
return `?? ""`
|
||||||
|
case "int":
|
||||||
|
return "?? 0"
|
||||||
|
case "double":
|
||||||
|
return "?? 0.0"
|
||||||
|
case "bool":
|
||||||
|
return "?? false"
|
||||||
|
default:
|
||||||
|
panic(errors.New("unknown atomic type"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if isListType(s) {
|
||||||
|
return "?? []"
|
||||||
|
}
|
||||||
|
if isMapType(s) {
|
||||||
|
return "?? {}"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
func getCoreType(s string) string {
|
func getCoreType(s string) string {
|
||||||
if isAtomicType(s) {
|
if isAtomicType(s) {
|
||||||
return s
|
return s
|
||||||
@@ -139,9 +185,13 @@ func specTypeToDart(tp spec.Type) (string, error) {
|
|||||||
}
|
}
|
||||||
return fmt.Sprintf("List<%s>", valueType), nil
|
return fmt.Sprintf("List<%s>", valueType), nil
|
||||||
case spec.InterfaceType:
|
case spec.InterfaceType:
|
||||||
return "Object", nil
|
return "Object?", nil
|
||||||
case spec.PointerType:
|
case spec.PointerType:
|
||||||
return specTypeToDart(v.Type)
|
valueType, err := specTypeToDart(v.Type)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s?", valueType), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.New("unsupported primitive type " + tp.Name())
|
return "", errors.New("unsupported primitive type " + tp.Name())
|
||||||
|
|||||||
@@ -8,6 +8,9 @@ var funcMap = template.FuncMap{
|
|||||||
"isDirectType": isDirectType,
|
"isDirectType": isDirectType,
|
||||||
"isNumberType": isNumberType,
|
"isNumberType": isNumberType,
|
||||||
"isClassListType": isClassListType,
|
"isClassListType": isClassListType,
|
||||||
|
"isNullableType": isNullableType,
|
||||||
|
"appendNullCoalescing": appendNullCoalescing,
|
||||||
|
"appendDefaultEmptyValue": appendDefaultEmptyValue,
|
||||||
"getCoreType": getCoreType,
|
"getCoreType": getCoreType,
|
||||||
"lowCamelCase": lowCamelCase,
|
"lowCamelCase": lowCamelCase,
|
||||||
"normalizeHandlerName": normalizeHandlerName,
|
"normalizeHandlerName": normalizeHandlerName,
|
||||||
|
|||||||
Reference in New Issue
Block a user