forked from lxm_flutter/json2dart
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bf4ebe233 | ||
|
|
103d92b610 | ||
|
|
6f007e8157 | ||
|
|
65cc06fe99 | ||
|
|
b507386ccc | ||
|
|
a0b0606c9d | ||
|
|
626512e475 | ||
|
|
bd858b22fb | ||
|
|
267425767a | ||
|
|
615e39db81 | ||
|
|
72303f53fc |
9
LICENSE
Normal file
9
LICENSE
Normal file
@@ -0,0 +1,9 @@
|
||||
Copyright 2018 cjl_spy@163.com
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,21 +1,39 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:json2dart_serialization/json_generator.dart';
|
||||
import 'package:json2dart_serialization/template.dart';
|
||||
|
||||
class Generator {
|
||||
String jsonString;
|
||||
String entityName;
|
||||
Version version;
|
||||
|
||||
Generator(this.jsonString, [this.entityName]);
|
||||
Generator(this.jsonString, [this.entityName, this.version = Version.v0]) {
|
||||
this.jsonString = convertJsonString(jsonString);
|
||||
}
|
||||
|
||||
List<DefaultTemplate> templateList = [];
|
||||
|
||||
String makeDartCode() {
|
||||
var entityName = this.entityName ?? "Entity";
|
||||
DefaultTemplate template = DefaultTemplate(srcJson: jsonString, className: entityName);
|
||||
DefaultTemplate template;
|
||||
if (version == Version.v1) {
|
||||
template = V1Template(srcJson: jsonString, className: entityName);
|
||||
} else {
|
||||
template = DefaultTemplate(srcJson: jsonString, className: entityName);
|
||||
}
|
||||
|
||||
StringBuffer resultSb = StringBuffer();
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
if (!template.isList) {
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
// return resultSb.toString();
|
||||
} else {
|
||||
var listTemplate = template.getListTemplate();
|
||||
templateList.add(listTemplate);
|
||||
|
||||
refreshTemplate(template);
|
||||
}
|
||||
|
||||
resultSb.writeln(header);
|
||||
templateList.forEach((template) {
|
||||
@@ -28,13 +46,14 @@ class Generator {
|
||||
var fieldList = template.fieldList;
|
||||
fieldList.forEach((filed) {
|
||||
if (filed is MapField) {
|
||||
// filed.typeString
|
||||
DefaultTemplate template = DefaultTemplate(srcJson: json.encode(filed.map), className: 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);
|
||||
DefaultTemplate template = DefaultTemplate(
|
||||
srcJson: json.encode(filed.list[0]), className: filed.typeName);
|
||||
templateList.add(template);
|
||||
refreshTemplate(template);
|
||||
}
|
||||
@@ -44,7 +63,8 @@ class Generator {
|
||||
|
||||
String get fileName => camelCase2UnderScoreCase(entityName);
|
||||
|
||||
static const String importString = "import 'package:json_annotation/json_annotation.dart';";
|
||||
static const String importString =
|
||||
"import 'package:json_annotation/json_annotation.dart';";
|
||||
|
||||
String get header => """$importString
|
||||
|
||||
@@ -60,3 +80,22 @@ String camelCase2UnderScoreCase(String name) {
|
||||
return "_" + str.toLowerCase();
|
||||
});
|
||||
}
|
||||
|
||||
/// use the string replace's method the resolve the int and double problem.
|
||||
String convertJsonString(String jsonString) {
|
||||
var numberReg = RegExp(r"[0-9]\.[0-9]+");
|
||||
|
||||
//匹配小数数字正则
|
||||
var allMatch = numberReg.allMatches(jsonString).toList();
|
||||
|
||||
for (var i = 0; i < allMatch.length; i++) {
|
||||
//是一个小数数字
|
||||
var m = allMatch[i];
|
||||
var s = m.group(0);
|
||||
|
||||
// 应该是double,但由于js的原因被识别成了整数数,这里对这种数据进行处理,将这里的最后一位从0替换为5,以便于让该被js识别成小数 而非数字
|
||||
s = s.replaceRange(s.length - 1, s.length, "5");
|
||||
jsonString = jsonString.replaceRange(m.start, m.end, s);
|
||||
}
|
||||
return jsonString;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/generator.dart';
|
||||
import 'package:json2dart_serialization/storage.dart';
|
||||
|
||||
String entityName = null;
|
||||
|
||||
@@ -22,28 +23,36 @@ var downloadFileName = "";
|
||||
// }""";
|
||||
const defaultValue = "";
|
||||
|
||||
enum Version { v0, v1 }
|
||||
|
||||
Version v = Version.v0;
|
||||
|
||||
void main() async {
|
||||
isChinese = await _isChinese();
|
||||
|
||||
var dataHelper = CookieHelper();
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
jsonInput.value = defaultValue;
|
||||
jsonInput.value = dataHelper.loadJsonString();
|
||||
|
||||
jsonInput.onInput.listen((event) {
|
||||
// print(jsonInput.value);
|
||||
dataHelper.saveJsonString(jsonInput.value);
|
||||
refreshData();
|
||||
});
|
||||
|
||||
InputElement entityNameEle = querySelector("#out_entity_name");
|
||||
entityNameEle.value = dataHelper.loadEntityName();
|
||||
entityName = entityNameEle.value;
|
||||
entityNameEle.onInput.listen((event) {
|
||||
entityName = entityNameEle.value;
|
||||
dataHelper.saveEntityName(entityName);
|
||||
refreshData();
|
||||
});
|
||||
|
||||
ButtonElement formatButton = querySelector("#format");
|
||||
formatButton.onClick.listen((click) {
|
||||
String pretty;
|
||||
pretty = convertJsonString(jsonInput.value);
|
||||
try {
|
||||
pretty = formatJson(jsonInput.value);
|
||||
pretty = formatJson(pretty);
|
||||
} on Exception {
|
||||
return;
|
||||
}
|
||||
@@ -53,6 +62,39 @@ void main() async {
|
||||
InputElement eJsonKey = querySelector("#use_json_key");
|
||||
InputElement eCamelCase = querySelector("#camelCase");
|
||||
TextAreaElement result = querySelector("#result");
|
||||
RadioButtonInputElement v0 = querySelector("#v0");
|
||||
RadioButtonInputElement v1 = querySelector("#v1");
|
||||
|
||||
void updateVersioin() {
|
||||
if (v1.checked) {
|
||||
v = Version.v1;
|
||||
} else {
|
||||
v = Version.v0;
|
||||
}
|
||||
|
||||
dataHelper.saveVersion(v);
|
||||
}
|
||||
|
||||
void updateVersionUI() {
|
||||
if (v == Version.v1) {
|
||||
v1.checked = true;
|
||||
} else {
|
||||
v1.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
v = dataHelper.loadVersion();
|
||||
|
||||
updateVersionUI();
|
||||
|
||||
v0.onInput.listen((event) {
|
||||
updateVersioin();
|
||||
refreshData();
|
||||
});
|
||||
v1.onInput.listen((event) {
|
||||
updateVersioin();
|
||||
refreshData();
|
||||
});
|
||||
|
||||
void onJsonKeyChange() {
|
||||
useJsonKey = eJsonKey.checked;
|
||||
@@ -101,7 +143,8 @@ void main() async {
|
||||
// FileWriter fw = await fileEntry.createWriter();
|
||||
// fw.write(blob);
|
||||
// File file = await fileEntry.file();
|
||||
AnchorElement saveLink = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
|
||||
AnchorElement saveLink =
|
||||
document.createElementNS("http://www.w3.org/1999/xhtml", "a");
|
||||
saveLink.href = Url.createObjectUrlFromBlob(blob);
|
||||
// saveLink.type = "download";
|
||||
saveLink.download = downloadFileName;
|
||||
@@ -133,10 +176,10 @@ bool isChinese = false;
|
||||
void refreshData() async {
|
||||
TextAreaElement jsonInput = querySelector("#json");
|
||||
var string = jsonInput.value;
|
||||
String pretty;
|
||||
TextAreaElement result = querySelector("#result");
|
||||
|
||||
try {
|
||||
pretty = formatJson(string);
|
||||
formatJson(string);
|
||||
} on Exception {
|
||||
if (isChinese) {
|
||||
result.value = "不是一个正确的json";
|
||||
@@ -152,7 +195,7 @@ void refreshData() async {
|
||||
entityClassName = entityName;
|
||||
}
|
||||
|
||||
var generator = Generator(string, entityClassName);
|
||||
var generator = Generator(string, entityClassName, v);
|
||||
var dartCode = generator.makeDartCode();
|
||||
var dartFileName = ("${generator.fileName}.dart");
|
||||
downloadFileName = dartFileName;
|
||||
@@ -163,7 +206,7 @@ void refreshData() async {
|
||||
} else {
|
||||
filePrefix = "your dart file name is:";
|
||||
}
|
||||
print(filePrefix);
|
||||
// print(filePrefix);
|
||||
querySelector("#file_name").text = "$filePrefix $dartFileName";
|
||||
|
||||
result.value = dartCode;
|
||||
|
||||
44
lib/storage.dart
Normal file
44
lib/storage.dart
Normal file
@@ -0,0 +1,44 @@
|
||||
import 'dart:html';
|
||||
|
||||
import 'package:json2dart_serialization/json_generator.dart';
|
||||
|
||||
const _entityKey = "entityKey";
|
||||
const _versionKey = "versionKey";
|
||||
|
||||
class CookieHelper {
|
||||
String loadJsonString() {
|
||||
var storage = window.localStorage;
|
||||
if (!storage.containsKey("json")) {
|
||||
return "";
|
||||
}
|
||||
return window.localStorage["json"];
|
||||
}
|
||||
|
||||
void saveJsonString(String jsonString) {
|
||||
window.localStorage.addAll({"json": jsonString});
|
||||
}
|
||||
|
||||
void saveEntityName(String entityName) {
|
||||
window.localStorage.addAll({_entityKey: entityName});
|
||||
}
|
||||
|
||||
String loadEntityName() {
|
||||
if (!window.localStorage.containsKey(_entityKey)) {
|
||||
return "";
|
||||
}
|
||||
return window.localStorage[_entityKey];
|
||||
}
|
||||
|
||||
void saveVersion(Version version) {
|
||||
var index = Version.values.indexOf(version);
|
||||
window.localStorage.addAll({_versionKey: index.toString()});
|
||||
}
|
||||
|
||||
Version loadVersion() {
|
||||
if (!window.localStorage.containsKey(_versionKey)) {
|
||||
return Version.v0;
|
||||
}
|
||||
|
||||
return Version.values[int.parse(window.localStorage[_versionKey])];
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,11 @@ class DefaultTemplate extends Template {
|
||||
@override
|
||||
String declare() {
|
||||
return """@JsonSerializable()
|
||||
class $className extends Object with _\$${className}SerializerMixin {""";
|
||||
class $className extends Object ${interface()}{""";
|
||||
}
|
||||
|
||||
String interface() {
|
||||
return "with _\$${className}SerializerMixin";
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -97,6 +101,84 @@ class $className extends Object with _\$${className}SerializerMixin {""";
|
||||
}
|
||||
|
||||
List<Field> get fieldList => FieldHelper(srcJson).getFields();
|
||||
|
||||
bool get isList => json.decode(srcJson) is List;
|
||||
|
||||
ListTemplate getListTemplate() {
|
||||
if (this is ListTemplate) {
|
||||
return this;
|
||||
}
|
||||
return ListTemplate(
|
||||
srcJson: srcJson, className: className, delegateTemplate: this);
|
||||
}
|
||||
}
|
||||
|
||||
class ListTemplate extends DefaultTemplate {
|
||||
Template delegateTemplate;
|
||||
|
||||
ListTemplate(
|
||||
{String srcJson, String className = "Entity", this.delegateTemplate})
|
||||
: super(className: className, srcJson: srcJson);
|
||||
|
||||
@override
|
||||
String declare() {
|
||||
return _declareListMethod() + "\n" + delegateTemplate?.declare() ??
|
||||
super.declare();
|
||||
}
|
||||
|
||||
String _declareListMethod() {
|
||||
var listMethod =
|
||||
"""List<$className> get${className}List(List<dynamic> list){
|
||||
List<$className> result = [];
|
||||
list.forEach((item){
|
||||
result.add($className.fromJson(item));
|
||||
});
|
||||
return result;
|
||||
}""";
|
||||
return listMethod;
|
||||
}
|
||||
|
||||
@override
|
||||
String constructor() {
|
||||
return delegateTemplate?.constructor() ?? super.constructor();
|
||||
}
|
||||
|
||||
@override
|
||||
String field() {
|
||||
return delegateTemplate?.field() ?? super.field();
|
||||
}
|
||||
|
||||
@override
|
||||
String method() {
|
||||
return delegateTemplate?.method() ?? super.method();
|
||||
}
|
||||
|
||||
@override
|
||||
String end() {
|
||||
return delegateTemplate?.end() ?? super.end();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Field> get fieldList =>
|
||||
FieldHelper(json.encode(json.decode(srcJson)[0])).getFields();
|
||||
}
|
||||
|
||||
class V1Template extends DefaultTemplate {
|
||||
V1Template({String srcJson, String className = "Entity"})
|
||||
: super(className: className, srcJson: srcJson);
|
||||
|
||||
@override
|
||||
String interface() => "";
|
||||
|
||||
@override
|
||||
String method() {
|
||||
var result = StringBuffer();
|
||||
result.writeln(super.method());
|
||||
result.writeln();
|
||||
result.write(
|
||||
" Map<String, dynamic> toJson() => _\$${className}ToJson(this);");
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
||||
class FieldHelper {
|
||||
@@ -104,26 +186,35 @@ class FieldHelper {
|
||||
|
||||
FieldHelper(this.srcJson);
|
||||
|
||||
List<Field> _getMapFiled(Map<String, dynamic> map) {
|
||||
List<Field> list = [];
|
||||
map.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;
|
||||
}
|
||||
|
||||
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 _getMapFiled(j);
|
||||
} else if (j is List) {
|
||||
var item = j[0];
|
||||
if (item is Map<String, dynamic>) {
|
||||
return _getMapFiled(item);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
BIN
web/github_logo.jpg
Normal file
BIN
web/github_logo.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
@@ -17,43 +17,51 @@
|
||||
<body>
|
||||
<div class="lang">
|
||||
<a href="index_ch.html">中文</a>
|
||||
<a href="https://github.com/caijinglong/json2dart">
|
||||
<img src="github_logo.jpg" width="50px" />
|
||||
</a>
|
||||
</div>
|
||||
<h1>simple use
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable" target="_blank">json_serializable</a>
|
||||
</h1>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">copy your json to left textarea</span>
|
||||
<span class="half_span">
|
||||
<div class="result_title">
|
||||
dart class name
|
||||
<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>
|
||||
<div id="file_name"></div>
|
||||
</span>
|
||||
<h1>simple use
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable" target="_blank">json_serializable</a>
|
||||
</h1>
|
||||
<div class="version">
|
||||
<input class="version" type="radio" value="0" name="version" id="v0" checked="true">v0.x.x</input>
|
||||
<input class="version" type="radio" value="1" name="version" id="v1">v1.x.x</input>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="half_span">
|
||||
<textarea id="json" title="json" class="content_area"></textarea>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<textarea id="result" title="result" class="content_area"></textarea>
|
||||
</span>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">copy your json to left textarea</span>
|
||||
<span class="half_span">
|
||||
<div class="result_title">
|
||||
dart class name
|
||||
<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>
|
||||
<div id="file_name"></div>
|
||||
</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span class="half_span">
|
||||
<textarea id="json" title="json" class="content_area"></textarea>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<textarea id="result" title="result" class="content_area"></textarea>
|
||||
</span>
|
||||
</div>
|
||||
<div class="func">
|
||||
<span class="half_span">
|
||||
<button id="format">format</button>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<button id="copy">copy</button>
|
||||
<button id="save">download</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="func">
|
||||
<span class="half_span">
|
||||
<button id="format">format</button>
|
||||
</span>
|
||||
<span class="half_span">
|
||||
<button id="copy">copy</button>
|
||||
<button id="save">download</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -17,9 +17,19 @@
|
||||
<body>
|
||||
<div class="lang">
|
||||
<a href="index.html">English</a>
|
||||
<a href="https://github.com/caijinglong/json2dart">
|
||||
<img src="github_logo.jpg" width="50px" />
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<h1>为了便利使用
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable">json_serializable</a>库
|
||||
</h1>
|
||||
<div class="version">
|
||||
<input class="version" type="radio" value="0" name="version" id="v0" checked="true">v0.x.x</input>
|
||||
<input class="version" type="radio" value="1" name="version" id="v1">v1.x.x</input>
|
||||
</div>
|
||||
</div>
|
||||
<h1>为了便利使用
|
||||
<a href="https://pub.dartlang.org/packages/json_serializable">json_serializable</a>库</h1>
|
||||
<div>
|
||||
<div class="title">
|
||||
<span class="half_span">将json粘贴至左边</span>
|
||||
|
||||
@@ -8,34 +8,6 @@ body {
|
||||
padding: 0;
|
||||
font-family: "Roboto", sans-serif;
|
||||
}
|
||||
/*
|
||||
.top {
|
||||
height: 4vh;
|
||||
text-align: center;
|
||||
padding-top: 1vh;
|
||||
}
|
||||
|
||||
.result_title {
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.textarea {
|
||||
width: 50%;
|
||||
height: 90%;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.content_area {
|
||||
width: 80%;
|
||||
height: 90vh;
|
||||
text-align: center;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.out_entity_name {
|
||||
height: 40px;
|
||||
} */
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
@@ -86,3 +58,8 @@ a {
|
||||
a:hover {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
|
||||
.version {
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user