-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
85daaf8
commit 62fff6e
Showing
24 changed files
with
1,024 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.idea | ||
dist/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
# go-to-dart | ||
|
||
Go-to-dart helps you convert Go structs to Dart classes that can be used with [json_serializable](https://pub.dev/packages/json_serializable). | ||
|
||
## Features | ||
|
||
- Supports only structs in the same package (no generics or embedded structs yet) | ||
- Supports primitives, slices, maps, and pointers | ||
- Support some other arbitrary types such as `time.Time` and `mo.Option` (easy to extend!) | ||
|
||
Need something more? Please open an issue or even better, a PR! | ||
|
||
## Installation | ||
|
||
```bash | ||
go install github.com/11wizards/go-to-dart | ||
``` | ||
|
||
The above command will install go-to-dart in your `$GOPATH/bin` directory. Make sure that directory is in your `$PATH`. | ||
|
||
## Usage | ||
|
||
```bash | ||
go-to-dart -i ./examples/user -o ./examples/user | ||
``` | ||
|
||
## Example | ||
|
||
Running the command above would take the package `./examples/user` below and generate a file `./examples/user/user.dart`. | ||
|
||
```go | ||
package user | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
type User struct { | ||
ID int | ||
Name string | ||
Email string | ||
Password string | ||
CreatedAt time.Time | ||
UpdatedAt time.Time | ||
DeletedAt *time.Time | ||
Options map[string]string | ||
Tags []string | ||
} | ||
``` | ||
|
||
Contents of `./examples/user/user.dart`: | ||
```dart | ||
import 'package:json_annotation/json_annotation.dart'; | ||
part 'user.g.dart'; | ||
@JsonSerializable() | ||
class User { | ||
@JsonKey(name: 'ID') final int id; | ||
@JsonKey(name: 'Name') final String name; | ||
@JsonKey(name: 'Email') final String email; | ||
@JsonKey(name: 'Password') final String password; | ||
@JsonKey(name: 'CreatedAt') final DateTime createdAt; | ||
@JsonKey(name: 'UpdatedAt') final DateTime updatedAt; | ||
@JsonKey(name: 'DeletedAt') final DateTime? deletedAt; | ||
@JsonKey(name: 'Options') final Map<String, String> options; | ||
@JsonKey(name: 'Tags') final List<String> tags; | ||
User({ | ||
required this.id, | ||
required this.name, | ||
required this.email, | ||
required this.password, | ||
required this.createdAt, | ||
required this.updatedAt, | ||
this.deletedAt, | ||
required this.options, | ||
required this.tags, | ||
}); | ||
Map<String, dynamic> toJson() => _$UserToJson(this); | ||
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
import 'package:json_annotation/json_annotation.dart'; | ||
|
||
part 'everything.g.dart'; | ||
|
||
@JsonSerializable() | ||
class Parent { | ||
final String id; | ||
final int number1; | ||
final List<int> number2; | ||
final int? number3; | ||
final List<int>? number4; | ||
final List<int?> number5; | ||
final int? number6; | ||
final List<int?> number7; | ||
final String text1; | ||
final List<String> text2; | ||
final String? text3; | ||
final List<String>? text4; | ||
final List<String?> text5; | ||
final String? text6; | ||
final List<String?> text7; | ||
final DateTime date1; | ||
final List<DateTime> date2; | ||
final DateTime? date3; | ||
final List<DateTime>? date4; | ||
final List<DateTime?> date5; | ||
final String? date6; | ||
final List<String?> date7; | ||
final Child child1; | ||
final List<Child> child2; | ||
final Child? child3; | ||
final List<Child>? child4; | ||
final List<Child?> child5; | ||
final Child? child6; | ||
final List<Child?> child7; | ||
final Map<String, double> map1; | ||
@JsonKey(name: 'map2_weird_name') final Map<int, Child> map2; | ||
|
||
Parent({ | ||
required this.id, | ||
required this.number1, | ||
required this.number2, | ||
this.number3, | ||
this.number4, | ||
required this.number5, | ||
this.number6, | ||
required this.number7, | ||
required this.text1, | ||
required this.text2, | ||
this.text3, | ||
this.text4, | ||
required this.text5, | ||
this.text6, | ||
required this.text7, | ||
required this.date1, | ||
required this.date2, | ||
this.date3, | ||
this.date4, | ||
required this.date5, | ||
this.date6, | ||
required this.date7, | ||
required this.child1, | ||
required this.child2, | ||
this.child3, | ||
this.child4, | ||
required this.child5, | ||
this.child6, | ||
required this.child7, | ||
required this.map1, | ||
required this.map2, | ||
}); | ||
|
||
Map<String, dynamic> toJson() => _$ParentToJson(this); | ||
|
||
factory Parent.fromJson(Map<String, dynamic> json) => _$ParentFromJson(json); | ||
} | ||
|
||
@JsonSerializable() | ||
class Child { | ||
final int id; | ||
final String name; | ||
|
||
Child({ | ||
required this.id, | ||
required this.name, | ||
}); | ||
|
||
Map<String, dynamic> toJson() => _$ChildToJson(this); | ||
|
||
factory Child.fromJson(Map<String, dynamic> json) => _$ChildFromJson(json); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package everything | ||
|
||
import ( | ||
"github.com/samber/mo" | ||
"time" | ||
) | ||
|
||
type ParentID string | ||
|
||
type Parent struct { | ||
ID ParentID `json:"id"` | ||
|
||
Number1 int `json:"number1"` | ||
Number2 []int `json:"number2"` | ||
Number3 *int `json:"number3"` | ||
Number4 *[]int `json:"number4"` | ||
Number5 []*int `json:"number5"` | ||
Number6 mo.Option[int] `json:"number6"` | ||
Number7 []mo.Option[int] `json:"number7"` | ||
|
||
Text1 string `json:"text1"` | ||
Text2 []string `json:"text2"` | ||
Text3 *string `json:"text3"` | ||
Text4 *[]string `json:"text4"` | ||
Text5 []*string `json:"text5"` | ||
Text6 mo.Option[string] `json:"text6"` | ||
Text7 []mo.Option[string] `json:"text7"` | ||
|
||
Date1 time.Time `json:"date1"` | ||
Date2 []time.Time `json:"date2"` | ||
Date3 *time.Time `json:"date3"` | ||
Date4 *[]time.Time `json:"date4"` | ||
Date5 []*time.Time `json:"date5"` | ||
Date6 mo.Option[string] `json:"date6"` | ||
Date7 []mo.Option[string] `json:"date7"` | ||
|
||
Child1 Child `json:"child1"` | ||
Child2 []Child `json:"child2"` | ||
Child3 *Child `json:"child3"` | ||
Child4 *[]Child `json:"child4"` | ||
Child5 []*Child `json:"child5"` | ||
Child6 mo.Option[Child] `json:"child6"` | ||
Child7 []mo.Option[Child] `json:"child7"` | ||
|
||
Map1 map[string]float64 `json:"map1"` | ||
Map2 map[ChildID]Child `json:"map2_weird_name"` | ||
} | ||
|
||
type ChildID int64 | ||
|
||
type Child struct { | ||
ID ChildID `json:"id"` | ||
Name string `json:"name"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import 'package:json_annotation/json_annotation.dart'; | ||
|
||
part 'user.g.dart'; | ||
|
||
@JsonSerializable() | ||
class User { | ||
@JsonKey(name: 'ID') final int id; | ||
@JsonKey(name: 'Name') final String name; | ||
@JsonKey(name: 'Email') final String email; | ||
@JsonKey(name: 'Password') final String password; | ||
@JsonKey(name: 'CreatedAt') final DateTime createdAt; | ||
@JsonKey(name: 'UpdatedAt') final DateTime updatedAt; | ||
@JsonKey(name: 'DeletedAt') final DateTime? deletedAt; | ||
@JsonKey(name: 'Options') final Map<String, String> options; | ||
@JsonKey(name: 'Tags') final List<String> tags; | ||
|
||
User({ | ||
required this.id, | ||
required this.name, | ||
required this.email, | ||
required this.password, | ||
required this.createdAt, | ||
required this.updatedAt, | ||
this.deletedAt, | ||
required this.options, | ||
required this.tags, | ||
}); | ||
|
||
Map<String, dynamic> toJson() => _$UserToJson(this); | ||
|
||
factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package user | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
type User struct { | ||
ID int | ||
Name string | ||
Email string | ||
Password string | ||
CreatedAt time.Time | ||
UpdatedAt time.Time | ||
DeletedAt *time.Time | ||
Options map[string]string | ||
Tags []string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package generator | ||
|
||
import ( | ||
"fmt" | ||
"github.com/openconfig/goyang/pkg/indent" | ||
"go/ast" | ||
"io" | ||
) | ||
|
||
func generateFields(wr io.Writer, st *ast.StructType) { | ||
for _, f := range st.Fields.List { | ||
generateFieldDeclaration(wr, f) | ||
fmt.Fprintln(wr, ";") | ||
} | ||
fmt.Fprintln(wr) | ||
} | ||
|
||
func generateConstructor(wr io.Writer, ts *ast.TypeSpec, st *ast.StructType) { | ||
fmt.Fprintf(wr, "%s({\n", ts.Name) | ||
|
||
for _, f := range st.Fields.List { | ||
generateFieldConstrutor(indent.NewWriter(wr, "\t"), f) | ||
fmt.Fprintln(wr, ",") | ||
} | ||
|
||
fmt.Fprintf(wr, "});") | ||
fmt.Fprintln(wr) | ||
fmt.Fprintln(wr) | ||
} | ||
|
||
func generateSerialization(wr io.Writer, ts *ast.TypeSpec) { | ||
fmt.Fprintf(wr, "Map<String, dynamic> toJson() => _$%sToJson(this);\n\n", ts.Name) | ||
} | ||
|
||
func generateDeserialization(wr io.Writer, ts *ast.TypeSpec) { | ||
fmt.Fprintf(wr, "factory %s.fromJson(Map<String, dynamic> json) => _$%sFromJson(json);\n", ts.Name, ts.Name) | ||
} | ||
|
||
func generateDartClass(outputFile io.Writer, ts *ast.TypeSpec, st *ast.StructType) bool { | ||
fmt.Fprintln(outputFile, "@JsonSerializable()") | ||
fmt.Fprintf(outputFile, "class %s {\n", ts.Name) | ||
|
||
wr := indent.NewWriter(outputFile, "\t") | ||
|
||
generateFields(wr, st) | ||
generateConstructor(wr, ts, st) | ||
generateSerialization(wr, ts) | ||
generateDeserialization(wr, ts) | ||
|
||
fmt.Fprintln(outputFile, "}") | ||
fmt.Fprintln(outputFile, "") | ||
|
||
return false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package generator | ||
|
||
import ( | ||
"fmt" | ||
"github.com/11wizards/go-to-dart/generator/format" | ||
"go/ast" | ||
"io" | ||
) | ||
|
||
func generateFieldDeclaration(writer io.Writer, f *ast.Field) { | ||
formatter := format.GetTypeFormatter(f.Type) | ||
fieldName := format.GetFieldName(f) | ||
jsonFieldName := format.GetJSONFieldName(f) | ||
|
||
if jsonFieldName != "" && jsonFieldName != fieldName { | ||
fmt.Fprintf(writer, "@JsonKey(name: '%s') ", jsonFieldName) | ||
} else if jsonFieldName == "" { | ||
fmt.Fprintf(writer, "@JsonKey(name: '%s') ", f.Names[0].Name) | ||
} | ||
|
||
fmt.Fprintf(writer, "final %s", formatter.Declaration(format.GetFieldName(f), f.Type)) | ||
} | ||
|
||
func generateFieldConstrutor(writer io.Writer, f *ast.Field) { | ||
formatter := format.GetTypeFormatter(f.Type) | ||
fmt.Fprint(writer, formatter.Constructor(format.GetFieldName(f), f.Type)) | ||
} |
Oops, something went wrong.