153 lines
4.6 KiB
C++
153 lines
4.6 KiB
C++
/*
|
|
{{copyright}}
|
|
*/
|
|
|
|
/*
|
|
{{version}}
|
|
*/
|
|
|
|
/*
|
|
{{license}}
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace sdi_toolBox::console
|
|
{
|
|
//--------------------------------------------------------------
|
|
class ConsoleTable
|
|
{
|
|
public:
|
|
using Row = std::vector<std::string>;
|
|
using ColumnWidths = std::vector<size_t>;
|
|
|
|
public:
|
|
ConsoleTable() = default; // Constructor
|
|
virtual ~ConsoleTable() = default; // Destructor
|
|
ConsoleTable(const ConsoleTable &other) = delete; // Copy constructor
|
|
ConsoleTable(ConsoleTable &&other) noexcept = delete; // Move constructor
|
|
ConsoleTable &operator=(const ConsoleTable &other) = delete; // Copy assignment
|
|
ConsoleTable &operator=(ConsoleTable &&other) noexcept = delete; // Move assignment
|
|
|
|
void setHeaders(const Row &headers); // Set table headers
|
|
void addRow(const Row &row); // Add a row to the table
|
|
|
|
[[nodiscard]] std::string render() const; // Render the table as a string
|
|
|
|
protected:
|
|
Row m_headers; // Table headers
|
|
std::vector<Row> m_rows; // Table rows
|
|
size_t m_padding = 2; // Padding between columns
|
|
|
|
private:
|
|
[[nodiscard]] ColumnWidths calculateColumnWidths() const; // Calculate column widths
|
|
[[nodiscard]] static std::string drawSeparator(const ColumnWidths &columnWidths); // Draw a separator line (+---+---+---+)
|
|
[[nodiscard]] static std::string drawRow(const Row &row, // Draw a single row
|
|
const ColumnWidths &columnWidths);
|
|
};
|
|
//--------------------------------------------------------------
|
|
/* Set table headers */
|
|
inline void ConsoleTable::setHeaders(const Row &headers)
|
|
{
|
|
m_headers = headers;
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Add a row to the table */
|
|
inline void ConsoleTable::addRow(const Row &row)
|
|
{
|
|
m_rows.push_back(row);
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Render the table as a string */
|
|
inline std::string ConsoleTable::render() const
|
|
{
|
|
// Calculate column widths
|
|
const auto columnWidths = calculateColumnWidths();
|
|
|
|
// Initialize the output string
|
|
std::string output;
|
|
|
|
// Draw the top separator
|
|
output += drawSeparator(columnWidths);
|
|
|
|
// Draw the headers
|
|
output += drawRow(m_headers, columnWidths);
|
|
|
|
// Draw the separator between headers and data
|
|
output += drawSeparator(columnWidths);
|
|
|
|
// Draw the data rows
|
|
for (const auto &row : m_rows)
|
|
{
|
|
output += drawRow(row, columnWidths);
|
|
}
|
|
|
|
// Draw the bottom separator
|
|
output += drawSeparator(columnWidths);
|
|
|
|
return output;
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Calculate column widths */
|
|
inline ConsoleTable::ColumnWidths ConsoleTable::calculateColumnWidths() const
|
|
{
|
|
// Determine the number of columns (based on headers or first row)
|
|
const auto numColumns = m_headers.empty() ? (m_rows.empty() ? 0 : m_rows[0].size()) : m_headers.size();
|
|
|
|
// Initialize column widths
|
|
ColumnWidths widths(numColumns, 0);
|
|
|
|
// Calculate widths based on headers
|
|
for (size_t i = 0; i < m_headers.size() && i < numColumns; ++i)
|
|
{
|
|
widths[i] = std::max(widths[i], m_headers[i].length() + m_padding);
|
|
}
|
|
|
|
// Calculate widths based on rows
|
|
for (const auto &row : m_rows)
|
|
{
|
|
for (size_t i = 0; i < row.size() && i < numColumns; ++i)
|
|
{
|
|
widths[i] = std::max(widths[i], row[i].length() + m_padding);
|
|
}
|
|
}
|
|
|
|
return widths;
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Draw a separator line (+---+---+---+) */
|
|
inline std::string ConsoleTable::drawSeparator(const ColumnWidths &columnWidths)
|
|
{
|
|
std::string output;
|
|
output += "+";
|
|
for (const auto &width : columnWidths)
|
|
{
|
|
output += std::string(width, '-') + "+";
|
|
}
|
|
output += "\n";
|
|
return output;
|
|
}
|
|
//--------------------------------------------------------------
|
|
/* Draw a single row */
|
|
inline std::string ConsoleTable::drawRow(const Row &row, const ColumnWidths &columnWidths)
|
|
{
|
|
std::string output;
|
|
output += "|";
|
|
for (size_t i = 0; i < columnWidths.size(); ++i)
|
|
{
|
|
const auto cellContent = (i < row.size()) ? row[i] : "";
|
|
output += " " + cellContent;
|
|
// Add padding spaces
|
|
const size_t paddingSpaces = columnWidths[i] - cellContent.length() - 1;
|
|
output += std::string(paddingSpaces, ' ');
|
|
output += "|";
|
|
}
|
|
output += "\n";
|
|
return output;
|
|
}
|
|
//--------------------------------------------------------------
|
|
} // namespace sdi_toolBox::console
|