diff --git a/CHANGELOG.md b/CHANGELOG.md index 33ba33d..6edebdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,9 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed -- Update to Kotlin 2.1.0. +- Update to Kotlin 2.1.0 (🏅 kudos to theyoz). - Update to Kotlinx-Serialization 1.7.3. - Make `CsvConfig` public. +- Support for streaming via Reader and Appendable (🏅 kudos to UnknownJoe796). +- Handle Microsoft Excel's insistence on using a byte order marker (🏅 kudos to UnknownJoe796). ### Removed diff --git a/library/src/main/kotlin/kotlinx/serialization/csv/Csv.kt b/library/src/main/kotlin/kotlinx/serialization/csv/Csv.kt index b966d13..8f633a8 100644 --- a/library/src/main/kotlin/kotlinx/serialization/csv/Csv.kt +++ b/library/src/main/kotlin/kotlinx/serialization/csv/Csv.kt @@ -62,17 +62,6 @@ sealed class Csv(val config: CsvConfig) : StringFormat { output.encode(serializer, value) } - /** - * Serialize [values] into CSV record(s). - * - * @param serializer The serializer used to serialize the given object. - * @param values The [Serializable] objects as a sequence. - * @param appendable The output where the CSV will be written. - */ - fun encodeSequenceToAppendable(serializer: KSerializer, values: Sequence, appendable: Appendable) { - values.forEach(beginEncodingToAppendable(serializer, appendable)) - } - /** * Start serializing values into CSV record(s). * @@ -107,38 +96,6 @@ sealed class Csv(val config: CsvConfig) : StringFormat { fun decodeFrom(deserializer: DeserializationStrategy, input: Reader): T = FetchSource(input).decode(deserializer) - /** - * Serialize [value] into CSV record(s). - * - * @param serializer The serializer used to serialize the given object. - * @param value The [Serializable] object. - */ - private fun Appendable.encode(serializer: SerializationStrategy, value: T) { - RootCsvEncoder( - csv = this@Csv, - output = this - ).encodeSerializableValue(serializer, value) - } - - /** - * Parse CSV from [this] input into [Serializable] object. - * - * @param deserializer The deserializer used to parse the given CSV string. - */ - private fun Source.decode(deserializer: DeserializationStrategy): T { - val reader = CsvReader( - source = this, - config = config - ) - - return RootCsvDecoder( - csv = this@Csv, - reader = reader, - ).decodeSerializableValue(deserializer).also { - require(reader.isDone) { "Reader has not consumed the whole input: $reader" } - } - } - /** * Parse CSV line-by-line from the given [reader] into a sequence. * @@ -182,6 +139,38 @@ sealed class Csv(val config: CsvConfig) : StringFormat { } } + /** + * Serialize [value] into CSV record(s). + * + * @param serializer The serializer used to serialize the given object. + * @param value The [Serializable] object. + */ + private fun Appendable.encode(serializer: SerializationStrategy, value: T) { + RootCsvEncoder( + csv = this@Csv, + output = this + ).encodeSerializableValue(serializer, value) + } + + /** + * Parse CSV from [this] input into [Serializable] object. + * + * @param deserializer The deserializer used to parse the given CSV string. + */ + private fun Source.decode(deserializer: DeserializationStrategy): T { + val reader = CsvReader( + source = this, + config = config + ) + + return RootCsvDecoder( + csv = this@Csv, + reader = reader, + ).decodeSerializableValue(deserializer).also { + require(reader.isDone) { "Reader has not consumed the whole input: $reader" } + } + } + internal class Impl(config: CsvConfig) : Csv(config) /**