[dart-gen] Support Null-safe and omitempty json tag (#3134)

master
fondoger 2 years ago committed by GitHub
parent bbfce6abe9
commit 078825b4eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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,

Loading…
Cancel
Save