[banshee] [Hyena.Json] Make serializer into extension methods



commit dc9ff32b4abd9a5b586761684259f073ec025abb
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Fri Feb 12 08:56:05 2010 -0800

    [Hyena.Json] Make serializer into extension methods
    
    One big win of this approach is you can call ToJsonString on any
    Enumerable or Dictionary<s,o>:
    
      Enumerable.Range (0, 4).ToJsonString ();

 src/Libraries/Hyena/Hyena.Json/ExtensionMethods.cs |  110 ++++++++++++++++++++
 src/Libraries/Hyena/Hyena.Json/IJsonCollection.cs  |    1 -
 src/Libraries/Hyena/Hyena.Json/JsonArray.cs        |   31 +-----
 src/Libraries/Hyena/Hyena.Json/JsonObject.cs       |   31 +-----
 .../Hyena/Hyena.Json/Tests/SerializerTests.cs      |   22 ++++-
 src/Libraries/Hyena/Hyena.csproj                   |    1 +
 src/Libraries/Hyena/Makefile.am                    |    1 +
 7 files changed, 138 insertions(+), 59 deletions(-)
---
diff --git a/src/Libraries/Hyena/Hyena.Json/ExtensionMethods.cs b/src/Libraries/Hyena/Hyena.Json/ExtensionMethods.cs
new file mode 100644
index 0000000..0b1de90
--- /dev/null
+++ b/src/Libraries/Hyena/Hyena.Json/ExtensionMethods.cs
@@ -0,0 +1,110 @@
+//
+// ExtensionMethods.cs
+//
+// Author:
+//   Gabriel Burt <gabriel burt gmail com>
+//
+// Copyright (c) 2010 Novell, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Hyena.Json
+{
+    public static class ExtensionMethods
+    {
+        // JsonObject serializer
+        public static string ToJsonString (this Dictionary<string, object> obj)
+        {
+            return obj.ToJsonString (1);
+        }
+
+        public static string ToJsonString (this Dictionary<string, object> obj, int level)
+        {
+            var sb = new StringBuilder ();
+            obj.ToJsonString (sb, level);
+            return sb.ToString ();
+        }
+
+        public static void ToJsonString (this Dictionary<string, object> obj, StringBuilder sb, int level)
+        {
+            if (obj.Count == 0) {
+                sb.AppendLine ("{ }");
+                return;
+            }
+
+            sb.AppendLine ("{");
+            foreach (KeyValuePair<string, object> item in obj) {
+                sb.AppendFormat ("{0}\"{1}\" : ", String.Empty.PadLeft (level * 2, ' '), item.Key);
+                item.Value.ToJsonString (sb, level + 1);
+            }
+            sb.AppendFormat ("{0}}}\n", String.Empty.PadLeft ((level - 1) * 2, ' '));
+        }
+
+        // JsonArray serializer
+        public static string ToJsonString (this IEnumerable list)
+        {
+            return list.ToJsonString (1);
+        }
+
+        public static string ToJsonString (this IEnumerable list, int level)
+        {
+            var sb = new StringBuilder ();
+            list.ToJsonString (sb, level);
+            return sb.ToString ();
+        }
+
+        public static void ToJsonString (this IEnumerable list, StringBuilder sb, int level)
+        {
+            bool first = true;
+            sb.Append ("[");
+            foreach (object item in list) {
+                if (first) {
+                    first = false;
+                    sb.AppendLine ();
+                }
+
+                sb.Append (String.Empty.PadLeft (level * 2, ' '));
+                item.ToJsonString (sb, level + 1);
+            }
+
+            if (first) {
+                sb.Append (" ");
+            }
+
+            sb.AppendFormat ("{0}]\n", first ? "" : String.Empty.PadLeft ((level - 1) * 2, ' '));
+        }
+
+        // Utility method
+        private static void ToJsonString (this object item, StringBuilder sb, int level)
+        {
+            if (item is Dictionary<string, object>) {
+                ((Dictionary<string, object>)item).ToJsonString (sb, level);
+            } else if (item is IEnumerable && !(item is string)) {
+                ((IEnumerable)item).ToJsonString (sb, level);
+            } else {
+                sb.AppendLine (item.ToString ());
+            }
+        }
+    }
+}
diff --git a/src/Libraries/Hyena/Hyena.Json/IJsonCollection.cs b/src/Libraries/Hyena/Hyena.Json/IJsonCollection.cs
index d995a5e..8c653e8 100644
--- a/src/Libraries/Hyena/Hyena.Json/IJsonCollection.cs
+++ b/src/Libraries/Hyena/Hyena.Json/IJsonCollection.cs
@@ -36,6 +36,5 @@ namespace Hyena.Json
     {
         void Dump ();
         void Dump (int count);
-        void Dump (StringBuilder sb, int level);
     }
 }
diff --git a/src/Libraries/Hyena/Hyena.Json/JsonArray.cs b/src/Libraries/Hyena/Hyena.Json/JsonArray.cs
index 23fff5f..e1d5331 100644
--- a/src/Libraries/Hyena/Hyena.Json/JsonArray.cs
+++ b/src/Libraries/Hyena/Hyena.Json/JsonArray.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Text;
 
@@ -41,38 +42,12 @@ namespace Hyena.Json
 
         public void Dump (int level)
         {
-            Console.Write (ToString (level));
+            Console.Write (this.ToJsonString (level));
         }
 
         public override string ToString ()
         {
-            return ToString (1);
-        }
-
-        public string ToString (int level)
-        {
-            var sb = new StringBuilder ();
-            Dump (sb, level);
-            return sb.ToString ();
-        }
-
-        public void Dump (StringBuilder sb, int level)
-        {
-            if (Count == 0) {
-                sb.AppendLine ("[ ]");
-                return;
-            }
-
-            sb.AppendLine ("[");
-            foreach (object item in this) {
-                sb.Append (String.Empty.PadLeft (level * 2, ' '));
-                if (item is IJsonCollection) {
-                    ((IJsonCollection)item).Dump (sb, level + 1);
-                } else {
-                    sb.AppendLine (item.ToString ());
-                }
-            }
-            sb.AppendFormat ("{0}]\n", String.Empty.PadLeft ((level - 1) * 2, ' '));
+            return this.ToJsonString ();
         }
     }
 }
diff --git a/src/Libraries/Hyena/Hyena.Json/JsonObject.cs b/src/Libraries/Hyena/Hyena.Json/JsonObject.cs
index 4ec2091..22175ff 100644
--- a/src/Libraries/Hyena/Hyena.Json/JsonObject.cs
+++ b/src/Libraries/Hyena/Hyena.Json/JsonObject.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Text;
 
@@ -41,38 +42,12 @@ namespace Hyena.Json
 
         public void Dump (int level)
         {
-            Console.Write (ToString (level));
+            Console.Write (this.ToJsonString (level));
         }
 
         public override string ToString ()
         {
-            return ToString (1);
-        }
-
-        public string ToString (int level)
-        {
-            var sb = new StringBuilder ();
-            Dump (sb, level);
-            return sb.ToString ();
-        }
-
-        public void Dump (StringBuilder sb, int level)
-        {
-            if (Count == 0) {
-                sb.AppendLine ("{ }");
-                return;
-            }
-
-            sb.AppendLine ("{");
-            foreach (KeyValuePair<string, object> item in this) {
-                sb.AppendFormat ("{0}\"{1}\" : ", String.Empty.PadLeft (level * 2, ' '), item.Key);
-                if (item.Value is IJsonCollection) {
-                    ((IJsonCollection)item.Value).Dump (sb, level + 1);
-                } else {
-                    sb.AppendLine (item.Value.ToString ());
-                }
-            }
-            sb.AppendFormat ("{0}}}\n", String.Empty.PadLeft ((level - 1) * 2, ' '));
+            return this.ToJsonString ();
         }
     }
 }
diff --git a/src/Libraries/Hyena/Hyena.Json/Tests/SerializerTests.cs b/src/Libraries/Hyena/Hyena.Json/Tests/SerializerTests.cs
index e9c70c9..1e3e46a 100644
--- a/src/Libraries/Hyena/Hyena.Json/Tests/SerializerTests.cs
+++ b/src/Libraries/Hyena/Hyena.Json/Tests/SerializerTests.cs
@@ -4,7 +4,7 @@
 // Author:
 //   Gabriel Burt <gabriel burt gmail com>
 //
-// Copyright (c) 2010 Gabriel Burt
+// Copyright (c) 2010 Novell, Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining a copy
 // of this software and associated documentation files (the "Software"), to deal
@@ -27,6 +27,7 @@
 #if ENABLE_TESTS
 
 using System;
+using System.Linq;
 using System.Reflection;
 using NUnit.Framework;
 
@@ -58,16 +59,33 @@ namespace Hyena.Json.Tests
         [Test]
         public void Array ()
         {
+            var empty = new JsonArray ();
+            Assert.AreEqual ("[ ]\n", empty.ToString ());
+
+            empty.Add (new JsonArray ());
+            Assert.AreEqual ("[\n  [ ]\n]\n", empty.ToString ());
+
+            empty.Add (new JsonObject ());
+            Assert.AreEqual ("[\n  [ ]\n  { }\n]\n", empty.ToString ());
+
             var a = new JsonArray ();
             a.Add ("foo");
             a.Add (obj);
-
             Assert.AreEqual (array_serialized, a.ToString ());
         }
 
         [Test]
         public void ExtensionMethods ()
         {
+            Assert.AreEqual (
+                "[\n  0\n  1\n  2\n  3\n]\n",
+                Enumerable.Range (0, 4).ToJsonString ()
+            );
+
+            Assert.AreEqual (
+                "[\n  [\n    0\n    2\n  ]\n  [\n    1\n    3\n  ]\n]\n",
+                 Enumerable.Range (0, 4).GroupBy<int, bool> (i => i % 2 == 0).ToJsonString ()
+            );
         }
     }
 }
diff --git a/src/Libraries/Hyena/Hyena.csproj b/src/Libraries/Hyena/Hyena.csproj
index 71171a5..7c87d4c 100644
--- a/src/Libraries/Hyena/Hyena.csproj
+++ b/src/Libraries/Hyena/Hyena.csproj
@@ -178,6 +178,7 @@
     <Compile Include="Hyena.Metrics\Tests\MetricsTests.cs" />
     <Compile Include="Hyena.Metrics\MemorySampleStore.cs" />
     <Compile Include="Hyena.Json\Tests\SerializerTests.cs" />
+    <Compile Include="Hyena.Json\ExtensionMethods.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="Mono.Posix">
diff --git a/src/Libraries/Hyena/Makefile.am b/src/Libraries/Hyena/Makefile.am
index 9711362..f4961e8 100644
--- a/src/Libraries/Hyena/Makefile.am
+++ b/src/Libraries/Hyena/Makefile.am
@@ -58,6 +58,7 @@ SOURCES =  \
 	Hyena.Jobs/SimpleAsyncJob.cs \
 	Hyena.Jobs/Tests/SchedulerTests.cs \
 	Hyena.Json/Deserializer.cs \
+	Hyena.Json/ExtensionMethods.cs \
 	Hyena.Json/IJsonCollection.cs \
 	Hyena.Json/JsonArray.cs \
 	Hyena.Json/JsonObject.cs \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]