Skip to content

Instantly share code, notes, and snippets.

@allenlinli
Forked from zonble/gist:10a1b8c12918470c4c54
Last active September 3, 2016 05:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save allenlinli/b45924bfd933a12f9928 to your computer and use it in GitHub Desktop.
Save allenlinli/b45924bfd933a12f9928 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# encoding: utf-8
def parse_rules(obj):
assert obj != None
rules = []
stack = []
def _parse(key, item):
if isinstance(item, dict):
stack.append([key, dict])
for k in item:
_parse(k, item[k])
stack.pop()
elif isinstance(item, list):
stack.append([key, list])
if len(item) == 0:
rules.append(stack[:])
stack.pop()
return
a_child = item[0]
_parse("_", a_child)
stack.pop()
else:
types = [basestring, int, bool, float, type(None)]
for a_type in types:
if isinstance(item, a_type):
stack.append([key, a_type])
rules.append(stack[:])
stack.pop()
break
else:
raise Exception("Unknown type found")
_parse('/', obj)
return rules
def format_rule(rule):
return "/".join("%s(%s)" % (str(x[0]), str(x[1])) for x in rule)
def check_with_rule(rule, obj):
assert rule != None
assert obj != None
assert len(rule) > 0
stack = []
def _check(depth):
the_type = stack[-1][0][1]
the_obj = stack[-1][1]
assert isinstance(the_obj, the_type)
if isinstance(the_obj, dict):
depth += 1
rule_item = rule[depth]
rule_key = rule_item[0]
assert rule_key in the_obj
stack.append([rule_item, the_obj[rule_key]])
_check(depth)
if isinstance(the_obj, list):
depth += 1
rule_item = rule[depth]
for item in the_obj:
stack.append([rule_item, item])
_check(depth)
stack.pop()
stack.append([rule[0], obj])
_check(0)
if __name__ == "__main__":
EXAMPLE = '''
{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}}
'''
OUTPUT = '''
{"menu": {
"id": "1234",
"value": "2234",
"popup": {
"menuitem": [
{"value": "New1212", "onclick": "CreateNewDoc()"},
{"value": "Open1212", "onclick": "OpenDoc()"},
{"value": "Close1212", "onclick": "CloseDoc()"},
{"value": "Close3434", "onclick": "CloseDoc()"}
]
}
}}
'''
import json
example = json.loads(EXAMPLE)
rules = parse_rules(example)
output = json.loads(OUTPUT)
for rule in rules:
# print format_rule(rules)
check_with_rule(rule, output)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment