forked from lxm_flutter/json2dart
完成了主题逻辑
This commit is contained in:
@@ -1,17 +1,58 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:json2dart_serialization/template.dart';
|
||||
|
||||
class Generator {
|
||||
String jsonString;
|
||||
String fileName;
|
||||
Generator(this.jsonString, this.fileName);
|
||||
String entityName;
|
||||
|
||||
Generator(this.jsonString, this.fileName, [this.entityName]);
|
||||
|
||||
List<DefaultTemplate> templateList = [];
|
||||
|
||||
String makeDartCode() {
|
||||
Template template = DefaultTemplate();
|
||||
return jsonString;
|
||||
var entityName = this.entityName ?? "Entity";
|
||||
DefaultTemplate template =
|
||||
DefaultTemplate(srcJson: jsonString, className: entityName);
|
||||
StringBuffer resultSb = StringBuffer();
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
|
||||
resultSb.writeln(header);
|
||||
templateList.forEach((template) {
|
||||
resultSb.writeln(template.toString());
|
||||
});
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
static const String importString = "import 'package:json_annotation/json_annotation.dart';";
|
||||
void refreshTemplate(DefaultTemplate template) {
|
||||
var fieldList = template.fieldList;
|
||||
bool needRefresh = false;
|
||||
fieldList.forEach((filed) {
|
||||
if (filed is MapField) {
|
||||
// filed.typeString
|
||||
DefaultTemplate template = DefaultTemplate(
|
||||
srcJson: json.encode(filed.map), className: filed.typeString);
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
} else if (filed is ListField) {
|
||||
if (filed.childIsObject) {
|
||||
DefaultTemplate template = DefaultTemplate(
|
||||
srcJson: json.encode(filed.list[0]), className: filed.typeName);
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static const String importString =
|
||||
"import 'package:json_annotation/json_annotation.dart';";
|
||||
|
||||
String get header => """$importString
|
||||
part $fileName.g.dart;""";
|
||||
|
||||
part $fileName.g.dart;
|
||||
|
||||
""";
|
||||
}
|
||||
|
||||
108
lib/json_generator.dart
Normal file
108
lib/json_generator.dart
Normal file
@@ -0,0 +1,108 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/generator.dart';
|
||||
|
||||
String entityName = null;
|
||||
|
||||
bool useJsonKey = true;
|
||||
|
||||
bool isCamelCase = true;
|
||||
|
||||
const defaultValue = """{
|
||||
"body": "",
|
||||
"data": [1],
|
||||
"input_content":["1"],
|
||||
"list1":[{"name":"hello"}],
|
||||
"number": [1.02],
|
||||
"user":{"name":"abc"}
|
||||
}""";
|
||||
|
||||
void main() {
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
jsonInput.value = defaultValue;
|
||||
|
||||
jsonInput.onInput.listen((event) {
|
||||
refreshData();
|
||||
});
|
||||
|
||||
InputElement entityNameEle = querySelector("#out_entity_name");
|
||||
entityNameEle.onInput.listen((event) {
|
||||
entityName = entityNameEle.value;
|
||||
refreshData();
|
||||
});
|
||||
|
||||
ButtonElement formatButton = querySelector("#format");
|
||||
formatButton.onClick.listen((click) {
|
||||
String pretty;
|
||||
try {
|
||||
pretty = formatJson(jsonInput.value);
|
||||
} on Exception {
|
||||
return;
|
||||
}
|
||||
jsonInput.value = pretty;
|
||||
});
|
||||
|
||||
InputElement eJsonKey = querySelector("#use_json_key");
|
||||
InputElement eCamelCase = querySelector("#camelCase");
|
||||
|
||||
void onJsonKeyChange() {
|
||||
useJsonKey = eJsonKey.checked;
|
||||
eCamelCase.disabled = !useJsonKey;
|
||||
isCamelCase = false;
|
||||
refreshData();
|
||||
}
|
||||
|
||||
eJsonKey.checked = useJsonKey;
|
||||
eJsonKey.onInput.listen((event) {
|
||||
onJsonKeyChange();
|
||||
});
|
||||
|
||||
querySelector("#check_label").onClick.listen((event) {
|
||||
eJsonKey.checked = !eJsonKey.checked;
|
||||
onJsonKeyChange();
|
||||
});
|
||||
|
||||
eCamelCase.checked = isCamelCase;
|
||||
eCamelCase.onInput.listen((event) {
|
||||
isCamelCase = eCamelCase.checked;
|
||||
refreshData();
|
||||
});
|
||||
|
||||
querySelector("#camelCaseLabel").onClick.listen((event) {
|
||||
eCamelCase.checked = !eCamelCase.checked;
|
||||
refreshData();
|
||||
});
|
||||
|
||||
refreshData();
|
||||
}
|
||||
|
||||
void refreshData() {
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
var string = jsonInput.value;
|
||||
String pretty;
|
||||
TextAreaElement result = querySelector("#result");
|
||||
try {
|
||||
pretty = formatJson(string);
|
||||
} on Exception {
|
||||
result.value = "不是一个正确的json";
|
||||
return;
|
||||
}
|
||||
String entityClassName;
|
||||
if (entityName == null || entityName == "" || entityName.trim() == "") {
|
||||
entityClassName = "Entity";
|
||||
} else {
|
||||
entityClassName = entityName;
|
||||
}
|
||||
|
||||
var generator = Generator(string, 'test.dart', entityClassName);
|
||||
var dartCode = generator.makeDartCode();
|
||||
|
||||
result.value = dartCode;
|
||||
}
|
||||
|
||||
String formatJson(String jsonString) {
|
||||
var map = json.decode(jsonString);
|
||||
var prettyString = JsonEncoder.withIndent(" ").convert(map);
|
||||
return prettyString;
|
||||
}
|
||||
@@ -1,3 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:json2dart_serialization/json_generator.dart' as main;
|
||||
|
||||
abstract class Template {
|
||||
String declare();
|
||||
|
||||
@@ -8,43 +11,217 @@ abstract class Template {
|
||||
String method();
|
||||
|
||||
String end();
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return createCode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultTemplate extends Template {
|
||||
String srcJson;
|
||||
String className;
|
||||
|
||||
String tab = " ";
|
||||
|
||||
DefaultTemplate({this.srcJson, this.className = "Entity"});
|
||||
|
||||
@override
|
||||
String constructor() {
|
||||
// TODO: implement constructor
|
||||
var fieldList = FieldHelper(srcJson).getFields();
|
||||
var filedString = StringBuffer();
|
||||
fieldList.forEach((f) {
|
||||
filedString.write("this.${f.nameString},");
|
||||
});
|
||||
return "${tab}$className($filedString);";
|
||||
}
|
||||
|
||||
@override
|
||||
String declare() {
|
||||
// TODO: implement declare
|
||||
return """@JsonSerializable()
|
||||
class $className extends Object with _\$${className}SerializerMixin {""";
|
||||
}
|
||||
|
||||
@override
|
||||
String end() {
|
||||
// TODO: implement end
|
||||
return "}";
|
||||
}
|
||||
|
||||
@override
|
||||
String field() {
|
||||
// TODO: implement field
|
||||
// var useJsonKey
|
||||
|
||||
var fieldList = FieldHelper(srcJson).getFields();
|
||||
var sb = StringBuffer();
|
||||
fieldList.forEach((f) {
|
||||
sb.writeln();
|
||||
if (main.useJsonKey) {
|
||||
sb.writeln(" @JsonKey(name: '${f.nameString}')");
|
||||
}
|
||||
String nameString;
|
||||
if (main.isCamelCase) {
|
||||
nameString = camelCase(f.nameString);
|
||||
} else {
|
||||
nameString = f.nameString;
|
||||
}
|
||||
sb.writeln(" ${f.typeString} $nameString;");
|
||||
});
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String camelCase(String name) {
|
||||
StringBuffer sb = StringBuffer();
|
||||
var list = name.split("_");
|
||||
for (int i = 0; i < list.length; i++) {
|
||||
var item = list[i];
|
||||
String name = "";
|
||||
if (i == 0) {
|
||||
name = firstLetterLower(item);
|
||||
} else {
|
||||
name = firstLetterUpper(item);
|
||||
}
|
||||
sb.write(name);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String method() {
|
||||
// TODO: implement method
|
||||
return " factory $className.fromJson(Map<String, dynamic> srcJson) => _\$${className}(srcJson);";
|
||||
}
|
||||
|
||||
List<Field> get fieldList => FieldHelper(srcJson).getFields();
|
||||
}
|
||||
|
||||
class FieldHelper {
|
||||
String srcJson;
|
||||
|
||||
FieldHelper(this.srcJson);
|
||||
|
||||
List<Field> getFields() {
|
||||
var j = json.decode(srcJson);
|
||||
if (j is Map<String, dynamic>) {
|
||||
List<Field> list = [];
|
||||
j.forEach((k, v) {
|
||||
if (v is List) {
|
||||
list.add(ListField(v, k));
|
||||
} else if (v is String) {
|
||||
list.add(SimpleField("String", k));
|
||||
} else if (v is int) {
|
||||
list.add(SimpleField("int", k));
|
||||
} else if (v is double) {
|
||||
list.add(SimpleField("double", k));
|
||||
} else if (v is bool) {
|
||||
list.add(SimpleField("bool", k));
|
||||
} else if (v is Map<String, dynamic>) {
|
||||
list.add(MapField(v, k));
|
||||
}
|
||||
});
|
||||
return list;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Field {
|
||||
String get typeString;
|
||||
|
||||
String get nameString;
|
||||
}
|
||||
|
||||
class SimpleField extends Field {
|
||||
@override
|
||||
String typeString;
|
||||
|
||||
@override
|
||||
String nameString;
|
||||
|
||||
SimpleField(this.typeString, this.nameString);
|
||||
}
|
||||
|
||||
class ListField extends Field {
|
||||
List<dynamic> list;
|
||||
|
||||
@override
|
||||
String nameString;
|
||||
|
||||
ListField(this.list, this.nameString);
|
||||
|
||||
bool get childIsObject {
|
||||
if (list == null || list.isEmpty) {
|
||||
return false;
|
||||
}
|
||||
if (list[0] is Map<String, dynamic>) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
String get typeName {
|
||||
String type = "dynamic";
|
||||
if (list == null || list.isEmpty) {
|
||||
return type;
|
||||
}
|
||||
var item = list[0];
|
||||
|
||||
if (item is List) {
|
||||
type = "${ListField(item, "").typeString}";
|
||||
} else if (item is Map<String, dynamic>) {
|
||||
type = "${firstLetterUpper(nameString)}";
|
||||
} else if (item is int) {
|
||||
type = "int";
|
||||
} else if (item is double) {
|
||||
type = "double";
|
||||
} else if (item is String) {
|
||||
type = "String";
|
||||
} else if (item is bool) {
|
||||
type = "bool";
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
@override
|
||||
String get typeString {
|
||||
return "List<$typeName>";
|
||||
}
|
||||
}
|
||||
|
||||
class MapField extends Field {
|
||||
Map<String, dynamic> map;
|
||||
String nameString;
|
||||
|
||||
MapField(this.map, this.nameString);
|
||||
|
||||
@override
|
||||
String get typeString {
|
||||
return firstLetterUpper(nameString);
|
||||
}
|
||||
}
|
||||
|
||||
String createCode(Template template) {
|
||||
var code = """${template.declare()}
|
||||
${template.field()}
|
||||
${template.constructor()}
|
||||
${template.field()}
|
||||
${template.constructor()}
|
||||
|
||||
${template.method()}
|
||||
${template.method()}
|
||||
|
||||
${template.end()}
|
||||
|
||||
${template.end()}
|
||||
""";
|
||||
return code;
|
||||
}
|
||||
|
||||
String firstLetterUpper(String value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "";
|
||||
}
|
||||
return value[0].toUpperCase() + value.substring(1);
|
||||
}
|
||||
|
||||
String firstLetterLower(String value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "";
|
||||
}
|
||||
return value[0].toLowerCase() + value.substring(1);
|
||||
}
|
||||
|
||||
3
lib/test.dart
Normal file
3
lib/test.dart
Normal file
@@ -0,0 +1,3 @@
|
||||
void main() {
|
||||
print(1.0 is int);
|
||||
}
|
||||
@@ -27,6 +27,12 @@
|
||||
</div>
|
||||
<div id="output" class="textarea">
|
||||
<div class="top"></div>
|
||||
<div class="result_title">
|
||||
类名称
|
||||
<input id="out_entity_name"/>
|
||||
<input type="checkbox" id="use_json_key"/><span id="check_label">jsonKey annotation</span>
|
||||
<input type="checkbox" id="camelCase"/><span id="camelCaseLabel">use camelCase</span>
|
||||
</div>
|
||||
<textarea id="result" title="结果"></textarea>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,42 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/generator.dart';
|
||||
import 'package:json2dart_serialization/json_generator.dart' as app;
|
||||
|
||||
void main() {
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
jsonInput.onInput.listen((event) {
|
||||
var string = jsonInput.value;
|
||||
String pretty;
|
||||
TextAreaElement result = querySelector("#result");
|
||||
try {
|
||||
pretty = formatJson(string);
|
||||
} on Exception {
|
||||
print("格式化错误");
|
||||
result.value = "不是一个正确的json";
|
||||
return;
|
||||
}
|
||||
|
||||
var generator = Generator(string, 'test.dart');
|
||||
var dartCode = generator.makeDartCode();
|
||||
|
||||
result.value = dartCode;
|
||||
});
|
||||
|
||||
ButtonElement formatButton = querySelector("#format");
|
||||
formatButton.onClick.listen((click) {
|
||||
String pretty;
|
||||
try {
|
||||
pretty = formatJson(jsonInput.value);
|
||||
} on Exception {
|
||||
return;
|
||||
}
|
||||
jsonInput.value = pretty;
|
||||
});
|
||||
}
|
||||
|
||||
String formatJson(String jsonString) {
|
||||
var map = json.decode(jsonString);
|
||||
var prettyString = JsonEncoder.withIndent(" ").convert(map);
|
||||
return prettyString;
|
||||
app.main();
|
||||
}
|
||||
|
||||
@@ -26,3 +26,11 @@ textarea {
|
||||
width: 90%;
|
||||
height: 90vh;
|
||||
}
|
||||
|
||||
.result_title {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.out_entity_name{
|
||||
height: 40px;
|
||||
}
|
||||
Reference in New Issue
Block a user