class TablePrint::Printer

def self.table_print(data, options={})

def self.table_print(data, options={})
  p = new(data, options)
  p.table_print
end

def columns

def columns
  return @columns if @columns
  defaults = TablePrint::Printable.default_display_methods(@data.first)
  c = TablePrint::ConfigResolver.new(@data.first.class, defaults, @options)
  @columns = c.columns
end

def configged?

def configged?
  !!Config.for(@data.first.class)
end

def initialize(data, options={})

def initialize(data, options={})
  @data = Array(data).compact
  @options = options
  @columns = nil
  @start_time = Time.now
end

def message

def message
  return "Printed with config" if configged?
  (Time.now - @start_time).to_s
  # the message is used to initiate Returnable
  # whose argument is regarded in ruby 2.7.1 as string
  # (ruby 2.7.1 calls ".includes?" method on this argument)
end

def table_print

def table_print
  return "No data." if @data.empty?
  # it's groups all the way down
  # make a top-level group to hold everything we're about to do
  group = TablePrint::RowGroup.new
  # parse the config and attach it to the group
  columns.each do |c|
    group.set_column(c)
  end
  # copy data from original objects into the group
  group_data = (@data.first.is_a?(Hash) || @data.first.is_a?(Struct)) ? [@data] : @data
  group_data.each do |data|
    group.add_children(Fingerprinter.new.lift(columns, data))
  end
  # munge the tree of data we created, to condense the output
  group.collapse!
  return "No data." if group.columns.empty?
  # turn everything into a string for output
  [group.header, group.horizontal_separator, group.format].join("\n")
end