libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

Table.kt (2597B)


      1 /*
      2  * This file is part of LibEuFin.
      3  * Copyright (C) 2024 Taler Systems S.A.
      4 
      5  * LibEuFin is free software; you can redistribute it and/or modify
      6  * it under the terms of the GNU Affero General Public License as
      7  * published by the Free Software Foundation; either version 3, or
      8  * (at your option) any later version.
      9 
     10  * LibEuFin is distributed in the hope that it will be useful, but
     11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General
     13  * Public License for more details.
     14 
     15  * You should have received a copy of the GNU Affero General Public
     16  * License along with LibEuFin; see the file COPYING.  If not, see
     17  * <http://www.gnu.org/licenses/>
     18  */
     19 
     20 package tech.libeufin.common
     21 
     22 import tech.libeufin.common.ANSI.displayLength
     23 import kotlin.math.max
     24 
     25 data class ColumnStyle(
     26     val alignLeft: Boolean = true
     27 ) {
     28     companion object {
     29         val DEFAULT = ColumnStyle()
     30     }
     31 }
     32 
     33 fun printTable(
     34     columns: List<String>, 
     35     rows: List<List<String>>,
     36     separator: Char = '|',
     37     colStyle: List<ColumnStyle> = listOf()
     38 ) {
     39     val cols: List<Pair<String, Int>> = columns.mapIndexed { i, name -> 
     40         val maxRow: Int = rows.asSequence().map { 
     41             it[i].displayLength()
     42         }.maxOrNull() ?: 0
     43         Pair(name, max(name.displayLength(), maxRow))
     44     }
     45     val table = buildString {
     46         fun padding(length: Int) {
     47             repeat(length) { append (' ') }
     48         }
     49         var first = true
     50         for ((name, len) in cols) {
     51             if (!first) {
     52                 append(separator)
     53             } else {
     54                 first = false
     55             }
     56             val pad = len - name.displayLength()
     57             padding(pad / 2)
     58             append(name)
     59             padding(pad / 2 + if (pad % 2 == 0) { 0 } else { 1 })
     60         }
     61         append('\n')
     62         for (row in rows) {
     63             var first = true
     64             cols.forEachIndexed { i, met ->
     65                 val str = row[i]
     66                 val style = colStyle.getOrNull(i) ?: ColumnStyle.DEFAULT
     67                 if (!first) {
     68                     append(separator)
     69                 } else {
     70                     first = false
     71                 }
     72                 val (_, len) = met
     73                 val pad = len - str.displayLength()
     74                 if (style.alignLeft) {
     75                     append(str)
     76                     padding(pad)
     77                 } else {
     78                     padding(pad)
     79                     append(str)
     80                 }
     81             }
     82             append('\n')
     83         }
     84     }
     85     print(table)
     86 }