Patchwork [15/28] qapi: ordereddict, add to_json() method

login
register
mail settings
Submitter Michael Roth
Date Oct. 31, 2012, 10:35 p.m.
Message ID <1351722972-17801-16-git-send-email-mdroth@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/196032/
State New
Headers show

Comments

Michael Roth - Oct. 31, 2012, 10:35 p.m.
This allows OrderedDict() instances to be [pretty-]printed to
QAPI-compatible JSON structures with field ordering preserved. This is
useful for QIDL, which generates schemas programatically and exposes
them to users in various ways.

Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 scripts/ordereddict.py |   51 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 51 insertions(+)

Patch

diff --git a/scripts/ordereddict.py b/scripts/ordereddict.py
index 7242b50..f1f8c71 100644
--- a/scripts/ordereddict.py
+++ b/scripts/ordereddict.py
@@ -23,6 +23,21 @@ 
 from UserDict import DictMixin
 
 class OrderedDict(dict, DictMixin):
+    class Indent(object):
+        def __init__(self, enable=True, initial_spacing=4, initial_level=0):
+            self.enable = enable
+            self.level = initial_level
+            self.spacing = initial_spacing
+        def inc(self, n=1):
+            self.level += n
+            return self.level
+        def dec(self, n=1):
+            self.level -= n
+            return self.level
+        def prefix(self):
+            if self.enable:
+                return " " * (self.spacing * self.level)
+            return ""
 
     def __init__(self, *args, **kwds):
         if len(args) > 1:
@@ -125,3 +140,39 @@  class OrderedDict(dict, DictMixin):
 
     def __ne__(self, other):
         return not self == other
+
+    def __obj_to_json(self, node, pretty=True, indent_spacing=4, indent_level=0):
+        i = self.Indent(pretty, indent_spacing, indent_level)
+        text = ""
+
+        if isinstance(node, OrderedDict):
+            if indent_level == 0:
+                text += "%s{\n" % i.prefix()
+            else:
+                text += "{\n"
+            i.inc()
+            for (k, v) in node.items():
+                text += "%s'%s': %s" % (i.prefix(), k,
+                    self.__obj_to_json(v, pretty, i.spacing, i.level))
+            i.dec()
+            text += "%s}" % i.prefix()
+        elif isinstance(node, list):
+            text += "[\n"
+            i.inc()
+            for e in node:
+                text += "%s%s" % (i.prefix(),
+                    self.__obj_to_json(e, pretty, i.spacing, i.level))
+            i.dec()
+            text += "%s]" % i.prefix()
+        else:
+            text += repr(node)
+
+        if indent_level > 0:
+            text += ",\n"
+
+        if not pretty:
+            return text.replace("\n", " ")
+        return text
+
+    def to_json(self, pretty=True, indent_spacing=4, indent_level=0):
+        return self.__obj_to_json(self)