avro-kotlin / avro4k

Avro format support for Kotlin
Apache License 2.0
188 stars 36 forks source link

Making JSON pretty option configurable/selectable #104

Closed peidongtang closed 1 year ago

peidongtang commented 3 years ago

In the latest release v1.2.0, code for AvroJsonOutputStream hard-coded the pretty option to true, as showing below:

@OptIn(ExperimentalSerializationApi::class)
class AvroJsonOutputStream<T>(output: OutputStream,
                              converter: (T) -> GenericRecord,
                              schema: Schema) : DefaultAvroOutputStream<T>(output, converter, schema) {
   ... ...

   override val encoder: JsonEncoder = 
        EncoderFactory.get().jsonEncoder(schema, output, true) // here, set pretty option to true
}

It makes the JSON output not suitable for some data processing scenarios that requires no newLine in a json string. However, since the pretty option is hard-coded to true, there's no way for user to change it.

Reasons for not using workable like string replace ops or other JSON libraries:

So, I suggest to open the pretty option and configurable, and make AvroEncodeFormat's Json object becomes PrettyJson object and CompactJson object, as showing below

For AvroEncodeFormat

    // Before
    object Json : AvroEncodeFormat() {
          override fun <T> createOutputStream(
              output: OutputStream,
              schema: Schema,
              converter: (T) -> GenericRecord
          ) = AvroJsonOutputStream(output, converter, schema, true)
      }
    // After
    object PrettyJson : AvroEncodeFormat() {
        override fun <T> createOutputStream(
            output: OutputStream,
            schema: Schema,
            converter: (T) -> GenericRecord
        ) = AvroJsonOutputStream(output, converter, schema, true)
    }

    object CompactJson : AvroEncodeFormat() {
        override fun <T> createOutputStream(
            output: OutputStream,
            schema: Schema,
            converter: (T) -> GenericRecord
        ) = AvroJsonOutputStream(output, converter, schema, false)
    }

For AvroJsonOutputStream

// Before
@OptIn(ExperimentalSerializationApi::class)
class AvroJsonOutputStream<T>(output: OutputStream,
                              converter: (T) -> GenericRecord,
                              schema: Schema) : DefaultAvroOutputStream<T>(output, converter, schema) {
   ... ...

   override val encoder: JsonEncoder = 
        EncoderFactory.get().jsonEncoder(schema, output, true) // here, set pretty option to true
}
// After
@OptIn(ExperimentalSerializationApi::class)
class AvroJsonOutputStream<T>(output: OutputStream,
                              converter: (T) -> GenericRecord,
                              schema: Schema, pretty: Boolean = false) : DefaultAvroOutputStream<T>(output, converter, schema) {
   ... ...

   override val encoder: JsonEncoder = 
        EncoderFactory.get().jsonEncoder(schema, output, pretty) // here, set pretty option to true
}
Chuckame commented 1 year ago

Don't hesitate to make a PR. Since it's an old stale issue, I'm closing it.