from printer.FormatInstructions import FormatDetailDesc, FormatDetailType, FormatInstructions class Formatter: def __init__(self): self.custom_l_formats = {} self.custom_d_formats = [] def register_format_l(self, obj, template): key = FormatInstructions.get_obj_key(obj) self.custom_l_formats[key] = template return self def register_format_d(self, predicate, properties, format_type=FormatDetailType.Props_In_Line): if isinstance(properties, list): properties = dict([(p, "{" + p + "}") for p in properties]) self.custom_d_formats.append(FormatDetailDesc(predicate, format_type, properties)) return self def compute_format_l(self, custom_formats_override, key): if custom_formats_override and key in custom_formats_override: custom_template = custom_formats_override[key] if custom_template in ("+", "\\+", "+\\"): return custom_template elif custom_template.startswith("+"): registered_template = self.custom_l_formats[key] if key in self.custom_l_formats else "" return registered_template + custom_template[1:] elif custom_template.startswith("\\+"): return custom_template[1:] elif custom_template.endswith("\\+"): return custom_template[:-2] + "+" elif custom_template.endswith("+"): registered_template = self.custom_l_formats[key] if key in self.custom_l_formats else "" return custom_template[:-1] + registered_template else: return custom_template elif key in self.custom_l_formats: return self.custom_l_formats[key] else: return None def compute_format_d(self, custom_formats_override): if custom_formats_override and not self.custom_d_formats: return custom_formats_override if self.custom_d_formats and not custom_formats_override: return self.custom_d_formats if self.custom_d_formats and custom_formats_override: return self.custom_d_formats + custom_formats_override return [] def format_l(self, obj, custom_formats_override=None): key = FormatInstructions.get_obj_key(obj) format_l = self.compute_format_l(custom_formats_override, key) return self.to_string(obj, format_l) if format_l else str(obj) def format_d(self, obj, format_d_desc: FormatDetailDesc): max_prop_length = self.get_properties_max_length(format_d_desc.properties.keys()) res = "" for prop, template in format_d_desc.properties.items(): if res: res += "\n" #value = getattr(obj, prop) if hasattr(obj, prop) else "*Undefined*" res += prop.ljust(max_prop_length) + ": " + self.to_string(obj, template) return res @staticmethod def get_properties_max_length(properties): return max((len(p) for p in properties)) @staticmethod def to_string(obj, template): try: bag = obj.to_bag() if hasattr(obj, "to_bag") else obj.__dict__ return template.format(**bag) except KeyError: return "*Undefined*"