import copy from dataclasses import dataclass from enum import Enum from typing import Dict from core.concept import Concept from core.utils import get_full_qualified_name from parsers.ExpressionParser import ExprNode class FormatDetailType(Enum): Props_In_Line = "in line" # the properties are listed line by line Props_In_Column = "in column" # the properties are listed row by row @dataclass class FormatDetailDesc: """ class that describes how to print the details """ predicate: ExprNode # the detail will be printed if the predicate is matched format_type: FormatDetailType properties: Dict[str, str] # name of the property, format to use class FormatInstructions: def __init__(self, tab_indent=None, tab=None, no_color=None): self._tab_indent = 2 self._tab = "" self._no_color = False self.recursive_props = {} # which property that does in recursion and what depth self.format_l = {} # what format to use when printing obj line by line self.format_d = [] # list of FormatDetailDesc # keep track of the modifications self.modified = set() self.recursive_props_modified = set() self.format_l_modified = set() if tab_indent is not None: self.tab_indent = tab_indent if tab: self.tab = tab if no_color: self.no_color = no_color @property def tab(self): return self._tab @tab.setter def tab(self, value): self._tab = value self.modified.add("tab") @property def tab_indent(self): return self._tab_indent @tab_indent.setter def tab_indent(self, value): self._tab_indent = value self.modified.add("tab_indent") @property def no_color(self): return self._no_color @no_color.setter def no_color(self, value): self._no_color = value self.modified.add("no_color") def set_recurse(self, prop_name, depth): self.recursive_props[prop_name] = depth self.recursive_props_modified.add(prop_name) return self def recurse(self, property_name): clone = self.clone() clone.tab = self.tab + (" " * self.tab_indent) clone.recursive_props[property_name] -= 1 return clone def set_format_l(self, obj, template): key = self.get_obj_key(obj) self.format_l[key] = template self.format_l_modified.add(key) return self def add_format_d(self, predicate, properties, format_type=FormatDetailType.Props_In_Line): if isinstance(properties, list): properties = dict((p, "{" + p + " }") for p in properties) self.format_d.append(FormatDetailDesc(predicate, format_type, properties)) return self def clone(self): clone = copy.deepcopy(self) return clone def merge(self, other): for prop in other.modified: setattr(self, prop, getattr(other, prop)) for prop in other.recursive_props_modified: self.set_recurse(prop, other.recursive_props[prop]) for key in other.format_l_modified: self.set_format_l(key, other.format_l[key]) self.format_d.extend(other.format_d) return self @staticmethod def get_obj_key(obj): return obj.id if isinstance(obj, Concept) else \ obj if isinstance(obj, str) else \ get_full_qualified_name(obj)