Uses a set of headers, raw data, and a row parsing function, to print
    data to the terminal in a table of rows and columns.

    Args:
        headers (tuple of strings): The headers for each column of data
        data_list (list of dicts): Raw response data from the validator
        parse_row_fn (function): Parses a dict of data into a tuple of columns
            Expected args:
                data (dict): A single response object from the validator
            Expected return:
                cols (tuple): The properties to display in each column

def print_terminal_table(headers, data_list, parse_row_fn):
    """Uses a set of headers, raw data, and a row parsing function, to print
    data to the terminal in a table of rows and columns.

    Args:
        headers (tuple of strings): The headers for each column of data
        data_list (list of dicts): Raw response data from the validator
        parse_row_fn (function): Parses a dict of data into a tuple of columns
            Expected args:
                data (dict): A single response object from the validator
            Expected return:
                cols (tuple): The properties to display in each column
    """
    data_iter = iter(data_list)
    try:
        example = next(data_iter)
        example_row = parse_row_fn(example)
        data_iter = itertools.chain([example], data_iter)
    except StopIteration:
        example_row = [''] * len(headers)

    format_string = format_terminal_row(headers, example_row)

    top_row = format_string.format(*headers)
    print(top_row[0:-3] if top_row.endswith('...') else top_row)
    for data in data_iter:
        print(format_string.format(*parse_row_fn(data)))