mirror of
https://github.com/YunoHost-Apps/zwave-js-ui_ynh.git
synced 2024-09-03 18:06:00 +02:00
89 lines
3.4 KiB
Python
89 lines
3.4 KiB
Python
|
import re
|
||
|
|
||
|
import yaml
|
||
|
|
||
|
from .loader import hash_key, set_yaml_grammar
|
||
|
|
||
|
# try:
|
||
|
# from yaml import CSafeDumper as default_dumper
|
||
|
# except ImportError:
|
||
|
# from yaml import SafeDumper as default_dumper
|
||
|
|
||
|
|
||
|
class OrderedIndentlessDumper(yaml.SafeDumper):
|
||
|
pass
|
||
|
|
||
|
|
||
|
class OrderedDumper(yaml.SafeDumper):
|
||
|
def increase_indent(self, flow=False, indentless=False):
|
||
|
return super(OrderedDumper, self).increase_indent(flow, False)
|
||
|
|
||
|
def ignore_aliases(self, data):
|
||
|
return True
|
||
|
|
||
|
|
||
|
yaml_value_annotation_re = re.compile(r"^__yq_(?P<type>tag|style)_(?P<key>.+)__$")
|
||
|
yaml_item_annotation_re = re.compile(r"^__yq_(?P<type>tag|style)_(?P<key>\d+)_(?P<value>.+)__$")
|
||
|
|
||
|
|
||
|
def get_dumper(use_annotations=False, indentless=False, grammar_version="1.1"):
|
||
|
# if not (use_annotations or indentless):
|
||
|
# return default_dumper
|
||
|
|
||
|
def represent_dict(dumper, data):
|
||
|
pairs, custom_styles, custom_tags = [], {}, {}
|
||
|
for k, v in data.items():
|
||
|
if use_annotations and isinstance(k, str):
|
||
|
if k == "__yq_alias__":
|
||
|
continue
|
||
|
value_annotation = yaml_value_annotation_re.match(k)
|
||
|
if value_annotation and value_annotation.group("type") == "style":
|
||
|
custom_styles[value_annotation.group("key")] = v
|
||
|
continue
|
||
|
elif value_annotation and value_annotation.group("type") == "tag":
|
||
|
custom_tags[value_annotation.group("key")] = v
|
||
|
continue
|
||
|
pairs.append((k, v))
|
||
|
mapping = dumper.represent_mapping("tag:yaml.org,2002:map", pairs)
|
||
|
if use_annotations:
|
||
|
for k, v in mapping.value:
|
||
|
hashed_key = hash_key(k.value)
|
||
|
if hashed_key in custom_styles:
|
||
|
if isinstance(v, yaml.nodes.ScalarNode):
|
||
|
v.style = custom_styles[hashed_key]
|
||
|
elif custom_styles[hashed_key] == "flow":
|
||
|
v.flow_style = True
|
||
|
if hashed_key in custom_tags:
|
||
|
v.tag = custom_tags[hashed_key]
|
||
|
return mapping
|
||
|
|
||
|
def represent_list(dumper, data):
|
||
|
raw_list, custom_styles, custom_tags = [], {}, {}
|
||
|
for v in data:
|
||
|
if use_annotations and isinstance(v, str):
|
||
|
annotation = yaml_item_annotation_re.match(v)
|
||
|
if annotation and annotation.group("type") == "style":
|
||
|
custom_styles[annotation.group("key")] = annotation.group("value")
|
||
|
continue
|
||
|
elif annotation and annotation.group("type") == "tag":
|
||
|
custom_tags[annotation.group("key")] = annotation.group("value")
|
||
|
continue
|
||
|
raw_list.append(v)
|
||
|
sequence = dumper.represent_list(raw_list)
|
||
|
if use_annotations:
|
||
|
for i, v in enumerate(sequence.value):
|
||
|
if str(i) in custom_styles:
|
||
|
if isinstance(v, yaml.nodes.ScalarNode):
|
||
|
v.style = custom_styles[str(i)]
|
||
|
elif custom_styles[str(i)] == "flow":
|
||
|
v.flow_style = True
|
||
|
if str(i) in custom_tags:
|
||
|
v.tag = custom_tags[str(i)]
|
||
|
return sequence
|
||
|
|
||
|
dumper = OrderedIndentlessDumper if indentless else OrderedDumper
|
||
|
dumper.add_representer(dict, represent_dict)
|
||
|
dumper.add_representer(list, represent_list)
|
||
|
set_yaml_grammar(dumper, grammar_version=grammar_version)
|
||
|
return dumper
|