diff --git a/DartClassGenerator.cs b/DartClassGenerator.cs new file mode 100644 index 0000000..3e75c7c --- /dev/null +++ b/DartClassGenerator.cs @@ -0,0 +1,33 @@ +using Selim.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JsonToDart +{ + public class DartClassGenerator + { + public static Queue innerObjects = new Queue(); + + + public string generateDartClass(JsonObject jsonObject, string className) + { + innerObjects.Clear(); + jsonObject.setClassName(className); + var sb = new StringBuilder(); + // + jsonObject.createDartClass(sb); + // + while(innerObjects.Count > 0) + { + var obj = innerObjects.Dequeue(); + obj.createDartClass(sb); + } + // + return sb.ToString(); + } + + } +} diff --git a/Form1.Designer.cs b/Form1.Designer.cs index 2a58e09..7d2db38 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -37,12 +37,15 @@ private void InitializeComponent() this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.jsonTextBox = new System.Windows.Forms.TextBox(); this.dartTextBox = new System.Windows.Forms.TextBox(); + this.linkLabel1 = new System.Windows.Forms.LinkLabel(); + this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel1.SuspendLayout(); this.tableLayoutPanel2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); this.splitContainer1.Panel1.SuspendLayout(); this.splitContainer1.Panel2.SuspendLayout(); this.splitContainer1.SuspendLayout(); + this.tableLayoutPanel3.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel1 @@ -51,12 +54,14 @@ private void InitializeComponent() this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 0); this.tableLayoutPanel1.Controls.Add(this.splitContainer1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel3, 0, 2); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowCount = 3; this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 70F)); this.tableLayoutPanel1.Size = new System.Drawing.Size(2037, 1325); this.tableLayoutPanel1.TabIndex = 0; // @@ -70,7 +75,6 @@ private void InitializeComponent() this.tableLayoutPanel2.Controls.Add(this.classNameTextBox, 3, 0); this.tableLayoutPanel2.Controls.Add(this.convertBtn, 0, 0); this.tableLayoutPanel2.Controls.Add(this.label1, 2, 0); - this.tableLayoutPanel2.Controls.Add(this.button1, 1, 0); this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3); this.tableLayoutPanel2.Name = "tableLayoutPanel2"; @@ -90,8 +94,9 @@ private void InitializeComponent() // // convertBtn // - this.convertBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(255))))); + this.convertBtn.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(192))))); this.convertBtn.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.convertBtn.ForeColor = System.Drawing.Color.White; this.convertBtn.Location = new System.Drawing.Point(3, 3); this.convertBtn.Name = "convertBtn"; this.convertBtn.Size = new System.Drawing.Size(187, 56); @@ -112,9 +117,9 @@ private void InitializeComponent() // // button1 // - this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(192)))), ((int)(((byte)(192)))), ((int)(((byte)(255))))); + this.button1.BackColor = System.Drawing.Color.Silver; this.button1.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.button1.Location = new System.Drawing.Point(447, 3); + this.button1.Location = new System.Drawing.Point(1018, 3); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(361, 56); this.button1.TabIndex = 1; @@ -136,7 +141,7 @@ private void InitializeComponent() // splitContainer1.Panel2 // this.splitContainer1.Panel2.Controls.Add(this.dartTextBox); - this.splitContainer1.Size = new System.Drawing.Size(2031, 1240); + this.splitContainer1.Size = new System.Drawing.Size(2031, 1170); this.splitContainer1.SplitterDistance = 1001; this.splitContainer1.TabIndex = 0; // @@ -150,7 +155,7 @@ private void InitializeComponent() this.jsonTextBox.Name = "jsonTextBox"; this.jsonTextBox.PlaceholderText = "Paste json here"; this.jsonTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.jsonTextBox.Size = new System.Drawing.Size(1001, 1240); + this.jsonTextBox.Size = new System.Drawing.Size(1001, 1170); this.jsonTextBox.TabIndex = 0; // // dartTextBox @@ -163,9 +168,36 @@ private void InitializeComponent() this.dartTextBox.Name = "dartTextBox"; this.dartTextBox.ReadOnly = true; this.dartTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; - this.dartTextBox.Size = new System.Drawing.Size(1026, 1240); + this.dartTextBox.Size = new System.Drawing.Size(1026, 1170); this.dartTextBox.TabIndex = 1; // + // linkLabel1 + // + this.linkLabel1.AutoSize = true; + this.linkLabel1.Font = new System.Drawing.Font("Segoe UI", 10.875F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.linkLabel1.Location = new System.Drawing.Point(3, 0); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new System.Drawing.Size(297, 40); + this.linkLabel1.TabIndex = 1; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Serializable class code"; + this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + // + // tableLayoutPanel3 + // + this.tableLayoutPanel3.ColumnCount = 2; + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel3.Controls.Add(this.linkLabel1, 0, 0); + this.tableLayoutPanel3.Controls.Add(this.button1, 1, 0); + this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel3.Location = new System.Drawing.Point(3, 1258); + this.tableLayoutPanel3.Name = "tableLayoutPanel3"; + this.tableLayoutPanel3.RowCount = 1; + this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 50F)); + this.tableLayoutPanel3.Size = new System.Drawing.Size(2031, 64); + this.tableLayoutPanel3.TabIndex = 2; + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F); @@ -184,6 +216,8 @@ private void InitializeComponent() this.splitContainer1.Panel2.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit(); this.splitContainer1.ResumeLayout(false); + this.tableLayoutPanel3.ResumeLayout(false); + this.tableLayoutPanel3.PerformLayout(); this.ResumeLayout(false); } @@ -199,6 +233,8 @@ private void InitializeComponent() private System.Windows.Forms.Button button1; private System.Windows.Forms.Label label1; private System.Windows.Forms.TextBox classNameTextBox; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; + private System.Windows.Forms.LinkLabel linkLabel1; } } diff --git a/Form1.cs b/Form1.cs index 59a3178..9132c59 100644 --- a/Form1.cs +++ b/Form1.cs @@ -20,7 +20,7 @@ public Form1() private void Form1_Load(object sender, EventArgs e) { - + } private void tableLayoutPanel2_Paint(object sender, PaintEventArgs e) @@ -42,19 +42,35 @@ private void convertBtn_Click(object sender, EventArgs e) { if (String.IsNullOrWhiteSpace(jsonTextBox.Text)) return; // - var jp = new JsonParser(); - var json = jp.Parse(jsonTextBox.Text); + try + { + var jp = new JsonParser(); + var json = jp.Parse(jsonTextBox.Text); + + if (!(json is JsonObject)) + { + MessageBox.Show(this, "must be json object"); + return; + } + // + var jsonObject = json as JsonObject; + + var className = string.IsNullOrWhiteSpace(classNameTextBox.Text) ? "RootClass" + : classNameTextBox.Text; - if (!(json is JsonObject)) + var generator = new DartClassGenerator(); + + dartTextBox.Text = generator.generateDartClass(jsonObject, className); + } + catch (Exception ex) { - //ShowDialog() - return; + MessageBox.Show(this, ex.Message); } - // - var jObject = json as JsonObject; + } - jObject.setClassName(string.IsNullOrWhiteSpace(classNameTextBox.Text)? "RootClass" : classNameTextBox.Text); - dartTextBox.Text = jObject.createDartClass(new StringBuilder()); + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + new Form2().ShowDialog(this); } } } diff --git a/Form2.Designer.cs b/Form2.Designer.cs new file mode 100644 index 0000000..238f5c4 --- /dev/null +++ b/Form2.Designer.cs @@ -0,0 +1,100 @@ + +namespace JsonToDart +{ + partial class Form2 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form2)); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.dartTextBox = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.dartTextBox, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.button1, 0, 1); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 2; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 75F)); + this.tableLayoutPanel1.Size = new System.Drawing.Size(1299, 1135); + this.tableLayoutPanel1.TabIndex = 0; + // + // dartTextBox + // + this.dartTextBox.BackColor = System.Drawing.Color.White; + this.dartTextBox.Dock = System.Windows.Forms.DockStyle.Fill; + this.dartTextBox.Font = new System.Drawing.Font("Segoe UI", 10.875F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.dartTextBox.Location = new System.Drawing.Point(3, 3); + this.dartTextBox.Multiline = true; + this.dartTextBox.Name = "dartTextBox"; + this.dartTextBox.ReadOnly = true; + this.dartTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both; + this.dartTextBox.Size = new System.Drawing.Size(1293, 1054); + this.dartTextBox.TabIndex = 3; + this.dartTextBox.Text = resources.GetString("dartTextBox.Text"); + // + // button1 + // + this.button1.BackColor = System.Drawing.Color.Silver; + this.button1.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.button1.Location = new System.Drawing.Point(3, 1063); + this.button1.Name = "button1"; + this.button1.Size = new System.Drawing.Size(361, 56); + this.button1.TabIndex = 2; + this.button1.Text = "Copy to Clipboard"; + this.button1.UseVisualStyleBackColor = false; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // Form2 + // + this.AutoScaleDimensions = new System.Drawing.SizeF(13F, 32F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(1299, 1135); + this.Controls.Add(this.tableLayoutPanel1); + this.Name = "Form2"; + this.Text = "Serializable Class"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.TextBox dartTextBox; + } +} \ No newline at end of file diff --git a/Form2.cs b/Form2.cs new file mode 100644 index 0000000..4670244 --- /dev/null +++ b/Form2.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace JsonToDart +{ + public partial class Form2 : Form + { + public Form2() + { + InitializeComponent(); + } + + private void button1_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetText(dartTextBox.Text); + } + catch { } + } + } +} diff --git a/Form2.resx b/Form2.resx new file mode 100644 index 0000000..1120a4c --- /dev/null +++ b/Form2.resx @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + +import 'dart:convert'; + +abstract class Serializable { + + String serialize() { + return json.encode(this.toMap()); + } + + void deserialize(String text) { + this.fromMap(json.decode(text)); + } + + //abstract + Map<String, dynamic> toMap(); + + //abstract + void fromMap(Map<String, dynamic> map); +} + + \ No newline at end of file diff --git a/Json/JsonArray.cs b/Json/JsonArray.cs index 75cdf90..0a60c58 100644 --- a/Json/JsonArray.cs +++ b/Json/JsonArray.cs @@ -217,25 +217,25 @@ public override void toString(StringBuilder sb, int? indents) } - public override string dartTypeName => $"List<{((Length == 0 || values[0] is JsonNull)? "Object?" : values[0].dartTypeName)}>"; + public override string dartTypeName => $"List<{((Length == 0 || values[0] is JsonNull)? "Object?" : $"{values[0].dartTypeName}?")}>"; public override string toDartMapAssignmentExpr(string name) { - var nullType = (Length == 0 || values[0] is JsonNull); + var notObject = (Length == 0 || !(values[0] is JsonObject)); return $"\t\tif (this.{name} != null) {{\r\n" + - $"\t\t\tdata['{name}'] = this.{name}?.map((v) => v).toList();\r\n" + + $"\t\t\tdata['{name}'] = this.{name}!.map((v) => v{(notObject? "": "?.toMap()")}).toList();\r\n" + $"\t\t}}"; } public override string toDartMapFetchingExpr(string name) { - var nullType = (Length == 0 || values[0] is JsonNull); + var notObject = (Length == 0 || !(values[0] is JsonObject)); return $"\t\tif (map['{name}'] != null) {{\r\n" + $"\t\t\t{name} = [];\r\n" + $"\t\t\tmap['{name}'].forEach((v) {{\r\n"+ - $"\t\t\t\t{name}!.add(v);\r\n" + + $"\t\t\t\t{name}!.add({(notObject? "v" : $"({values[0].dartTypeName}()..fromMap(v))")});\r\n" + $"\t\t\t}});\r\n" + $"\t\t}}"; } diff --git a/Json/JsonObject.cs b/Json/JsonObject.cs index f2e012c..6e994e5 100644 --- a/Json/JsonObject.cs +++ b/Json/JsonObject.cs @@ -1,4 +1,5 @@ -using System; +using JsonToDart; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -172,13 +173,13 @@ public override void toString(StringBuilder sb, int? indents) public override string toDartMapAssignmentExpr(string name) { return $"\t\tif (this.{name} != null) {{\r\n" + - $"\t\t\tdata['{name}'] = this.{name}?.toMap();\r\n"+ + $"\t\t\tdata['{name}'] = this.{name}!.toMap();\r\n"+ $"\t\t}}"; } public override string toDartMapFetchingExpr(string name) { - return $"\t{name} = map['{name}'] != null ? ({dartTypeName}()..fromMap(map['{name}'])) : null;"; + return $"\t\t{name} = map['{name}'] != null ? ({dartTypeName}()..fromMap(map['{name}'])) : null;"; } string className; @@ -191,6 +192,16 @@ public string createDartClass(StringBuilder sb) // declarations foreach (var item in this.nameValues) { + if(item.value is JsonObject) + { + setInnerType(item.value as JsonObject, item.name); + } + // + if(item.value is JsonArray && (item.value as JsonArray).Length > 0 && (item.value as JsonArray).getValue(0) is JsonObject) + { + setInnerType((item.value as JsonArray).getValue(0) as JsonObject, item.name); + } + // sb.AppendLine(item.value.toDartFieldDeclaration(item.name)); } @@ -230,12 +241,27 @@ public string createDartClass(StringBuilder sb) sb.AppendLine("\t\treturn data;"); sb.AppendLine("\t}"); - sb.AppendLine("}"); + sb.AppendLine(); // return sb.ToString(); } + private void setInnerType(JsonObject jsonObject, string name) + { + jsonObject.setClassName(capitalizeFirstLetter(name)); + DartClassGenerator.innerObjects.Enqueue(jsonObject); + } + + public static string capitalizeFirstLetter(string source) + { + if (string.IsNullOrEmpty(source)) + return string.Empty; + char[] letters = source.ToCharArray(); + letters[0] = char.ToUpper(letters[0]); + return new string(letters); + } + } diff --git a/JsonToDart.sln b/JsonToDart.sln index 3ded2fe..f54b397 100644 --- a/JsonToDart.sln +++ b/JsonToDart.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31624.102 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonToDart", "JsonToDart.csproj", "{A3E767E9-5DEC-4C28-B932-2BF1E33B594D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Json2DartTests", "..\Json2DartTests\Json2DartTests.csproj", "{EA4EF44D-DAA5-4FB1-AB27-A0AD392F58AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {A3E767E9-5DEC-4C28-B932-2BF1E33B594D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A3E767E9-5DEC-4C28-B932-2BF1E33B594D}.Release|Any CPU.ActiveCfg = Release|Any CPU {A3E767E9-5DEC-4C28-B932-2BF1E33B594D}.Release|Any CPU.Build.0 = Release|Any CPU + {EA4EF44D-DAA5-4FB1-AB27-A0AD392F58AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA4EF44D-DAA5-4FB1-AB27-A0AD392F58AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA4EF44D-DAA5-4FB1-AB27-A0AD392F58AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA4EF44D-DAA5-4FB1-AB27-A0AD392F58AC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index cb838be..87ea3e6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,30 @@ # JsonToDart -A Dotnet App to create dart class from json +A Dotnet App to create dart class from json, taking null-safety into consideration + +The dart class extends `Serializable` base class + +Here is the `Serializable` class code + +```dart +import 'dart:convert'; + +abstract class Serializable { + + String serialize() { + return json.encode(this.toMap()); + } + + void deserialize(String text) { + this.fromMap(json.decode(text)); + } + + //abstract + Map toMap(); + + //abstract + void fromMap(Map map); +} + +``` -The dart class extends Serializable base class