
com.phasmidsoftware.render.Writable.scala Maven / Gradle / Ivy
/*
* Copyright (c) 2019. Phasmid Software
*/
package com.phasmidsoftware.render
/**
* Trait to enable rendering of a table to a sequential (non-hierarchical) output format.
*
* @tparam O the underlying type, for example, a StringBuilder.
*/
trait Writable[O] {
// TODO create some off-the-shelf Writables
/**
* Method to return an empty (i.e. new) instance of O
*
* @return
*/
def unit: O
/**
* Method to write a character sequence to the given instance o.
*
* @param o the instance of O whither the parameter x should be written.
* @param x the character sequence to be written.
* @return an instance of O which represents the updated output structure.
*/
def writeRaw(o: O)(x: CharSequence): O
/**
* Method to write a value of type Any to the given instance o, possibly quoted.
*
* @param o the instance of O whither the xs values should be written.
* @param x the row instance to be written.
* @return an instance of O which represents the updated output structure.
*/
def writeRow[Row <: Product](o: O)(x: Row): O = writeRaw(writeRowElements(o)(x.productIterator.toSeq))(newline)
/**
* Method to write a value of type Any to the given instance o, possibly quoted.
* Elements will be separated by the delimiter, but no newline is appended.
* Element strings may be enclosed in quotes if appropriate.
*
* @param o the instance of O whither the xs values should be written.
* @param xs the sequence of elements (values) to be written.
* @return an instance of O which represents the updated output structure.
*/
def writeRowElements(o: O)(xs: Seq[Any]): O = {
// CONSIDER using foldLeft so that we can use the updated value of o at each step.
for (x <- xs.headOption) writeValue(o)(x)
for (x <- xs.tail) writeValue(writeRaw(o)(delimiter))(x)
o
}
private val sQuote: String = quote.toString
/**
* Method to write a value of type Any to the given instance o, possibly quoted.
*
* @param o the instance of O whither the parameter x should be written.
* @param x the character sequence to be written.
* @return an instance of O which represents the updated output structure.
*/
def writeValue(o: O)(x: Any): O = if (x.toString.contains(delimiter.toString) || x.toString.contains(sQuote))
writeQuoted(o)(x.toString)
else
writeRaw(o)(x.toString)
/**
* Method to write a character sequence to the given instance o, but within quotes.
* Any quote characters in x will be doubled.
*
* @param o the instance of O whither the parameter x should be written.
* @param x the character sequence to be written.
* @return an instance of O which represents the updated output structure.
*/
def writeQuoted(o: O)(x: CharSequence): O = {
val w = x.toString.replaceAll(quote.toString, s"$quote$quote")
writeRaw(o)(s"$quote$w$quote")
}
/**
* The default quote is one double-quote symbol
*
* @return "
*/
def quote: CharSequence =
"""""""
/**
* The default delimiter is a comma followed by a space.
*
* @return ", "
*/
def delimiter: CharSequence = ", "
/**
* The default newline character is the newline.
*
* @return \n
*/
def newline: CharSequence = "\n"
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy