""" Top-level entries in a TOML file. """ from prettytoml import elements from prettytoml.elements import TableElement, TableHeaderElement from .peekableit import PeekableIterator class TopLevel: """ A abstract top-level entry. """ def __init__(self, names, table_element): self._table_element = table_element self._names = Name(names) @property def table_element(self): return self._table_element @property def name(self): """ The distinct name of a table entry as an Name instance. """ return self._names class Name: def __init__(self, names): self._names = names @property def sub_names(self): return self._names def drop(self, n=0): """ Returns the name after dropping the first n entries of it. """ return Name(names=self._names[n:]) def is_prefixed_with(self, names): if isinstance(names, Name): return self.is_prefixed_with(names.sub_names) for i, name in enumerate(names): if self._names[i] != name: return False return True def without_prefix(self, names): if isinstance(names, Name): return self.without_prefix(names.sub_names) for i, name in enumerate(names): if name != self._names[i]: return Name(self._names[i:]) return Name(names=self.sub_names[len(names):]) @property def is_qualified(self): return len(self._names) > 1 def __str__(self): return '.'.join(self.sub_names) def __hash__(self): return hash(str(self)) def __eq__(self, other): return str(self) == str(other) def __ne__(self, other): return not self.__eq__(other) class AnonymousTable(TopLevel): def __init__(self, table_element): TopLevel.__init__(self, ('',), table_element) class Table(TopLevel): def __init__(self, names, table_element): TopLevel.__init__(self, names=names, table_element=table_element) class ArrayOfTables(TopLevel): def __init__(self, names, table_element): TopLevel.__init__(self, names=names, table_element=table_element) def _validate_file_elements(file_elements): pass def identify(file_elements): """ Outputs an ordered sequence of instances of TopLevel types. Elements start with an optional TableElement, followed by zero or more pairs of (TableHeaderElement, TableElement). """ if not file_elements: return _validate_file_elements(file_elements) # An iterator over enumerate(the non-metadata) elements iterator = PeekableIterator((element_i, element) for (element_i, element) in enumerate(file_elements) if element.type != elements.TYPE_METADATA) try: _, first_element = iterator.peek() if isinstance(first_element, TableElement): iterator.next() yield AnonymousTable(first_element) except KeyError: pass except StopIteration: return for element_i, element in iterator: if not isinstance(element, TableHeaderElement): continue # If TableHeader of a regular table, return Table following it if not element.is_array_of_tables: table_element_i, table_element = next(iterator) yield Table(names=element.names, table_element=table_element) # If TableHeader of an array of tables, do your thing else: table_element_i, table_element = next(iterator) yield ArrayOfTables(names=element.names, table_element=table_element)