commit | 1c35d91869131602976fffc9c031ce45744ae15f | [log] [tgz] |
---|---|---|
author | Leonid Startsev <sandwwraith@gmail.com> | Wed Oct 04 12:26:43 2017 +0300 |
committer | Leonid Startsev <sandwwraith@gmail.com> | Wed Oct 04 12:26:43 2017 +0300 |
tree | 85ba03bf6420ca63bde13bc17a82c8b8ccd96fb5 | |
parent | 1e3804845a0cdc55d91d2d646e4dc8c293382b40 [diff] |
Publish all projects, including common
Kotlin serialization support consists of three parts: a gradle compiler plugin, which produces visitor/serializer code for objects, an IntelliJ plugin and a runtime library.
@Serializable
and standard collections.This project contains the runtime library. Runtime library provides:
KInput
, KOutput
).ElementValueInput/Output
, NamedValueInput/Output
, ElementValueTransformer
)You can open example projects for JVM or JS to get started playing with it.
import kotlinx.serialization.* import kotlinx.serialization.json.JSON @Serializable data class Data(val a: Int, @Optional val b: String = "42") fun main(args: Array<String>) { println(JSON.stringify(Data(42))) // {"a": 42, "b": "42"} val obj = JSON.parse<Data>("""{"a":42}""") // Data(a=42, b="42") }
More examples of various kinds of Kotlin classes that can be serialized can be found here.
Runtime library provides three ready-to use formats: JSON, CBOR and ProtoBuf.
JSON format represented by JSON
class from kotlinx.serialization.json
package. It has constructor with four optional parameters:
You can also use one of predefined instances, like JSON.plain
, JSON.indented
, JSON.nonstrict
or JSON.unquoted
. API is duplicated in companion object, so JSON.parse(...)
equals to JSON.plain.parse(...)
JSON API:
fun <T> stringify(saver: KSerialSaver<T>, obj: T): String inline fun <reified T : Any> stringify(obj: T): String = stringify(T::class.serializer(), obj) fun <T> parse(loader: KSerialLoader<T>, str: String): T inline fun <reified T : Any> parse(str: String): T = parse(T::class.serializer(), str)
stringify
transforms object to string, parse
parses. No surprises.
Note: because JSON doesn't support maps with keys other than strings (and primitives), Kotlin maps with non-trivial key types are serialized as JSON lists.
CBOR
object doesn't support any tweaking and provides following functions:
fun <T : Any> dump(saver: KSerialSaver<T>, obj: T): ByteArray // saves object to bytes inline fun <reified T : Any> dump(obj: T): ByteArray // same as above, resolves serializer by itself inline fun <reified T : Any> dumps(obj: T): String // dump object and then pretty-print bytes to string fun <T : Any> load(loader: KSerialLoader<T>, raw: ByteArray): T // load object from bytes inline fun <reified T : Any> load(raw: ByteArray): T // save as above inline fun <reified T : Any> loads(hex: String): T // inverse operation for dumps
Note: CBOR, unlike JSON, supports maps with non-trivial keys, and Kotlin maps are serialized as CBOR maps, but some parsers (like jackson-dataformat-cbor
) don't support this.
Because protobuf relies on serial ids of fields, called 'tags', you have to provide this information, using serial annotation @SerialId
:
@Serializable data class KTestInt32(@SerialId(1) val a: Int)
This class is equivalent to the following proto definition:
message Int32 { required int32 a = 1; }
Note that we are using proto2 semantics, where all fields are explicitly required or optional.
Number format is set via @ProtoType
annotation. ProtoNumberType.DEFAULT
is default varint encoding (intXX
), SIGNED
is signed ZigZag representation (sintXX
), and FIXED
is fixedXX
type. uintXX
and sfixedXX
are not supported yet.
Repeated fields represented as lists. Because format spec says that if the list is empty, there will be no elements in the stream with such tag, you must explicitly mark any filed of list type with @Optional
annotation with default = emptyList()
. Same for maps.
Other known issues and limitations:
More examples of mappings from proto definitions to Koltin classes can be found in test data: here and here
Using Kotlin Serialization requires Kotlin compiler 1.1.50
or higher. Example projects on JVM are available for Gradle and Maven.
Ensure the proper version of Kotlin and add dependencies on plugin in addition to Kotlin compiler:
buildscript { ext.kotlin_version = '1.1.50' ext.serialization_version = '0.1' repositories { jcenter() maven { url "https://kotlin.bintray.com/kotlinx" } } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlinx:kotlinx-gradle-serialization-plugin:$serialization_version" } }
Don't forget to apply the plugin:
apply plugin: 'kotlin' apply plugin: 'kotlinx-serialization'
Add serialization runtime library in addition to Kotlin standard library and reflection (optional). For now, library requires small amount of reflection on runtime to find corresponding serializer for root-level type. In the future, we plan to move all resolving to separate module so the runtime library itself would not contain dependency on kotlin-reflect.
repositories { jcenter() maven { url "https://kotlin.bintray.com/kotlinx" } } dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version" }
Ensure the proper version of Kotlin and serialization version:
<properties> <kotlin.version>1.1.50</kotlin.version> <serialization.version>0.1</serialization.version> </properties>
Include bintray repository:
<repositories> <repository> <id>bintray-kotlin-kotlinx</id> <name>bintray</name> <url>https://kotlin.bintray.com/kotlinx</url> </repository> </repositories>
Add serialization plugin to Kotlin compiler plugin:
<build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> </executions> <configuration> <compilerPlugins> <plugin>kotlinx-serialization</plugin> </compilerPlugins> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-maven-serialization-plugin</artifactId> <version>${serialization.version}</version> </dependency> </dependencies> </plugin> </plugins> </build>
Add dependency on serialization runtime library:
<dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-serialization-runtime</artifactId> <version>${serialization.version}</version> </dependency>
Replace kotlinx-serialization-runtime
with kotlinx-serialization-runtime-js
to use it in JavaScript projects. JavaScript example is located at example-js
folder.
Unfortunately, embedded Kotlin compiler is not supported yet. To be able to run your project with serialization from within IDEA, perform following steps:
Settings - Build, Execution, Deployment - Build Tools - Gradle - Runner -
tick Delegate IDE build/run actions to gradle
.
For maven projects, create separate run configuration.