All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.http4k.format.ConfigurableJacksonCsv.kt Maven / Gradle / Ivy

There is a newer version: 5.36.0.0
Show newest version
package org.http4k.format

import com.fasterxml.jackson.dataformat.csv.CsvMapper
import com.fasterxml.jackson.dataformat.csv.CsvSchema
import org.http4k.asString
import org.http4k.core.Body
import org.http4k.core.ContentType
import org.http4k.core.HttpMessage
import org.http4k.core.with
import org.http4k.lens.BiDiBodyLensSpec
import org.http4k.lens.ContentNegotiation
import org.http4k.lens.Meta
import org.http4k.lens.ParamMeta.ObjectParam
import org.http4k.lens.httpBodyRoot
import java.io.StringWriter
import kotlin.reflect.KClass

open class ConfigurableJacksonCsv(val mapper: CsvMapper, val defaultContentType: ContentType = ContentType.TEXT_CSV) {

    inline fun  defaultSchema(): CsvSchema = mapper.schemaFor(T::class.java).withHeader()

    fun  writerFor(type: KClass, schema: CsvSchema): (List) -> String = { body: List ->
        StringWriter().use { stringWriter ->
            mapper.writerFor(type.java).with(schema).writeValues(stringWriter).use {
                it.writeAll(body)
            }
            stringWriter
        }.toString()
    }

    fun  readerFor(type: KClass, schema: CsvSchema): (String) -> List {
        val reader = mapper.readerFor(type.java).with(schema)
        return { body: String ->
            reader.readValues(body).readAll()
        }
    }

    inline fun  writeCsv(input: List, schema: CsvSchema = defaultSchema()): String {
        val writer = writerFor(T::class, schema)
        return writer(input)
    }

    inline fun  readCsv(input: String, schema: CsvSchema = defaultSchema()): List {
        val reader = readerFor(T::class, schema)
        return reader(input)
    }

    /**
     * Convenience function to write the object as CSV to the message body and set the content type.
     */
    inline fun  R.csv(t: List): R = with(Body.auto().toLens() of t)

    /**
     * Convenience function to read an object as CSV from the message body.
     */
    inline fun  HttpMessage.csv(): List = Body.auto().toLens()(this)

    inline fun  Body.Companion.auto(
        description: String? = null,
        contentNegotiation: ContentNegotiation = ContentNegotiation.None
    ) = autoBody(description, contentNegotiation)

    inline fun  autoBody(
        description: String? = null,
        contentNegotiation: ContentNegotiation = ContentNegotiation.None,
        contentType: ContentType = defaultContentType,
        schema: CsvSchema = defaultSchema()
    ): BiDiBodyLensSpec> {
        val reader = readerFor(T::class, schema)
        val writer = writerFor(T::class, schema)

        return httpBodyRoot(
            listOf(Meta(true, "body", ObjectParam, "body", description, emptyMap())),
            contentType,
            contentNegotiation
        )
            .map({ it.payload.asString() }, { Body(it) })
            .map(reader, writer)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy