Skip to content

Commit

Permalink
Add doc
Browse files Browse the repository at this point in the history
  • Loading branch information
petitcl committed May 14, 2023
1 parent 2d60279 commit 886d84b
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import kotlinx.serialization.modules.*
* @Serializable
* class DataHolder(val data: Data, val property2: String)
*
* val map = Properties.store(DataHolder(Data("value1"), "value2"))
* val map = Properties.encodeToMap(DataHolder(Data("value1"), "value2"))
* // map contents will be the following:
* // property2 = value2
* // data.property1 = value1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,64 @@ import kotlinx.serialization.encoding.*
import kotlinx.serialization.internal.*
import kotlinx.serialization.modules.*

/**
* Transforms a [Serializable] class' properties into a single flat [String] representing the class data
* in the properties format.
*
* If the given class has non-primitive property `d` of arbitrary type `D`, `D` values are inserted
* into the same map; keys for such values are prefixed with string `d.`:
*
* ```
* @Serializable
* class Data(val property1: String)
*
* @Serializable
* class DataHolder(val data: Data, val property2: String)
*
* val string = StringProperties.encodeToString(properties)
* // string contents will be the following:
* """
* property2 = value2
* data.property1 = value1
* """
* ```
*
* If the given class has a [List] property `l`, each value from the list
* would be prefixed with `l.N.`, where N is an index for a particular value.
* [Map] is treated as a `[key,value,...]` list.
* Conversely, this class can convert a properties string into a [Serializable] class instance.
* ```
* @Serializable
* class Data(val property1: String)
*
* @Serializable
* class DataHolder(val data: Data, val property2: String)
*
* val string = """
* property2 = value2
* data.property1 = value1
* """
* val data = StringProperties.decodeToString(string, DataHolder.serializer())
* // data contents will be the following:
* // DataHolder(data = Data(property1 = "value1"), property2 = "value2")
* ```
*
* @param conf A [PropertiesConf] which contain configuration for customising the output string.
*/
@ExperimentalSerializationApi
@Suppress("UNUSED_PARAMETER")
public sealed class StringProperties(
private val conf: PropertiesConf,
private val properties: Properties = Properties(conf.serializersModule),
) : SerialFormat by properties {
) : SerialFormat by properties, StringFormat {

/**
* Encodes properties from the given [value] to a properties String using the given [serializer].
* `null` values are omitted from the output.
*/
@ExperimentalSerializationApi
public fun <T> encodeToString(serializer: SerializationStrategy<T>, value: T): String {
public override fun <T> encodeToString(serializer: SerializationStrategy<T>, value: T): String {
val map = properties.encodeToMap(serializer, value)
val builder = StringBuilder()
for ((k, v) in map) {
Expand All @@ -45,12 +90,10 @@ public sealed class StringProperties(
* [String] values are converted to respective primitive types using default conversion methods.
* [T] may contain properties of nullable types; they will be filled by non-null values from the [map], if present.
*/
public fun <T> decodeFromString(deserializer: DeserializationStrategy<T>, string: String): T {
public override fun <T> decodeFromString(deserializer: DeserializationStrategy<T>, string: String): T {
val result = mutableMapOf<String, String>()
for (line in string.logicalLines()) {
println("line=`$line`")
val parsedLine = line.unescaped()
println("parsedLine=`$parsedLine`")
var keyEnd = parsedLine.length
for (i in parsedLine.indices) {
if (parsedLine[i] in separators) {
Expand All @@ -77,8 +120,6 @@ public sealed class StringProperties(

result[parsedLine.substring(0, keyEnd)] = parsedLine.substring(valueBegin)
}
println(result)
println(result.keys)
return properties.decodeFromStringMap(deserializer, result)
}

Expand All @@ -97,8 +138,8 @@ private class StringPropertiesImpl(conf: PropertiesConf) : StringProperties(conf
* TODO: doc
*/
@ExperimentalSerializationApi
public fun StringProperties(builderAction: PropertiesBuilder.() -> Unit = {}): StringProperties {
val builder = PropertiesBuilder(PropertiesConf())
public fun StringProperties(builderAction: StringPropertiesBuilder.() -> Unit = {}): StringProperties {
val builder = StringPropertiesBuilder(PropertiesConf())
builder.builderAction()
return StringPropertiesImpl(builder.build())
}
Expand All @@ -121,13 +162,40 @@ public inline fun <reified T> StringProperties.encodeToString(value: T): String
public inline fun <reified T> StringProperties.decodeFromString(propertiesString: String): T =
decodeFromString(serializersModule.serializer(), propertiesString)

/**
* Builder of the [StringProperties] instance provided by `StringProperties { ... }` factory function.
*/
@ExperimentalSerializationApi
public class PropertiesBuilder internal constructor(from: PropertiesConf) {
public class StringPropertiesBuilder internal constructor(from: PropertiesConf) {

/**
* A [LineSeparator] to be used for separating lines when encoding to a string.
* Default value is [LineSeparator.LF].
*/
public var lineSeparator: LineSeparator = from.lineSeparator

/**
* A [KeyValueSeparator] to be used for separating keys and values when encoding to a string.
* Default value is [KeyValueSeparator.EQUALS].
*/
public var keyValueSeparator: KeyValueSeparator = from.keyValueSeparator

/**
* A number of spaces to be inserted before the [keyValueSeparator] when encoding to a string.
* Default value is `0`.
*/
public var spacesBeforeSeparator: Int = from.spacesBeforeSeparator

/**
* A number of spaces to be inserted after the [keyValueSeparator] when encoding to a string.
* Default value is `0`.
*/
public var spacesAfterSeparator: Int = from.spacesAfterSeparator

/**
* A [SerializersModule] to be used for encoding and decoding.
* Default value is [EmptySerializersModule].
*/
public var module: SerializersModule = from.serializersModule

internal fun build(): PropertiesConf {
Expand Down

0 comments on commit 886d84b

Please sign in to comment.