diff --git a/README.md b/README.md index a6269dc1f1..59f443a2a4 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,8 @@ Kotlin serialization consists of a compiler plugin, that generates visitor code * [Introduction and references](#introduction-and-references) * [Setup](#setup) * [Gradle](#gradle) - * [Using the `plugins` block](#using-the-plugins-block) - * [Using `apply plugin` (the old way)](#using-apply-plugin-the-old-way) - * [Dependency on the JSON library](#dependency-on-the-json-library) + * [1) Setting up the serialization plugin](#1-setting-up-the-serialization-plugin) + * [2) Dependency on the JSON library](#2-dependency-on-the-json-library) * [Android](#android) * [Multiplatform (Common, JS, Native)](#multiplatform-common-js-native) * [Maven](#maven) @@ -83,9 +82,13 @@ Make sure you have the corresponding Kotlin plugin installed in the IDE, no addi ### Gradle -#### Using the `plugins` block +To set up kotlinx.serialization, you have to do two things: +1) Add the **[serialization plugin](#1-setting-up-the-serialization-plugin)**. +2) Add the **[serialization library dependency](#2-dependency-on-the-json-library)**. -You can set up the serialization plugin with the Kotlin plugin using +#### 1) Setting up the serialization plugin + +You can set up the serialization plugin with the Kotlin plugin using the [Gradle plugins DSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block): Kotlin DSL: @@ -106,9 +109,10 @@ plugins { } ``` -> Kotlin versions before 1.4.0 are not supported by the stable release of Kotlin serialization +> Kotlin versions before 1.4.0 are not supported by the stable release of Kotlin serialization. -#### Using `apply plugin` (the old way) +
+ Using apply plugin (the old way) First, you have to add the serialization plugin to your classpath as the other [compiler plugins](https://kotlinlang.org/docs/reference/compiler-plugins.html): @@ -145,10 +149,11 @@ Then you can `apply plugin` (example in Groovy): apply plugin: 'kotlin' // or 'kotlin-multiplatform' for multiplatform projects apply plugin: 'kotlinx-serialization' ``` +
-#### Dependency on the JSON library +#### 2) Dependency on the JSON library -After setting up the plugin one way or another, you have to add a dependency on the serialization library. +After setting up the plugin, you have to add a dependency on the serialization library. Note that while the plugin has version the same as the compiler one, runtime library has different coordinates, repository and versioning. Kotlin DSL: diff --git a/core/commonMain/src/kotlinx/serialization/ContextualSerializer.kt b/core/commonMain/src/kotlinx/serialization/ContextualSerializer.kt index 53fd4c30be..20e9ce1cfc 100644 --- a/core/commonMain/src/kotlinx/serialization/ContextualSerializer.kt +++ b/core/commonMain/src/kotlinx/serialization/ContextualSerializer.kt @@ -29,7 +29,7 @@ import kotlin.reflect.* * @Serializable * class ClassWithDate(val data: String, @Contextual val timestamp: Date) * - * val moduleForDate = serializersModule(MyISO8601DateSerializer) + * val moduleForDate = serializersModuleOf(MyISO8601DateSerializer) * val json = Json { serializersModule = moduleForDate } * json.encodeToString(ClassWithDate("foo", Date()) * ``` diff --git a/docs/serialization-guide.md b/docs/serialization-guide.md index 445d32e316..68ede1448b 100644 --- a/docs/serialization-guide.md +++ b/docs/serialization-guide.md @@ -71,6 +71,7 @@ Once the project is set up, we can start serializing some classes. * [Serializing 3rd party classes](serializers.md#serializing-3rd-party-classes) * [Passing a serializer manually](serializers.md#passing-a-serializer-manually) * [Specifying serializer on a property](serializers.md#specifying-serializer-on-a-property) + * [Specifying serializer for a particular type](serializers.md#specifying-serializer-for-a-particular-type) * [Specifying serializers for a file](serializers.md#specifying-serializers-for-a-file) * [Specifying serializer globally using typealias](serializers.md#specifying-serializer-globally-using-typealias) * [Custom serializers for a generic type](serializers.md#custom-serializers-for-a-generic-type) diff --git a/docs/serializers.md b/docs/serializers.md index 2da17fa43a..e6bf78e328 100644 --- a/docs/serializers.md +++ b/docs/serializers.md @@ -24,6 +24,7 @@ In this chapter we'll take a look at serializers in more detail, and we'll see h * [Serializing 3rd party classes](#serializing-3rd-party-classes) * [Passing a serializer manually](#passing-a-serializer-manually) * [Specifying serializer on a property](#specifying-serializer-on-a-property) + * [Specifying serializer for a particular type](#specifying-serializer-for-a-particular-type) * [Specifying serializers for a file](#specifying-serializers-for-a-file) * [Specifying serializer globally using typealias](#specifying-serializer-globally-using-typealias) * [Custom serializers for a generic type](#custom-serializers-for-a-generic-type) @@ -713,7 +714,7 @@ because we don't control the `Date` source code. There are several ways to work ### Passing a serializer manually All `encodeToXxx` and `decodeFromXxx` functions have an overload with the first serializer parameter. -When a non-serializable class, like `Date`, is the top-level class being serialized we can use those. +When a non-serializable class, like `Date`, is the top-level class being serialized, we can use those. ```kotlin fun main() { @@ -770,6 +771,45 @@ The `stableReleaseDate` property is serialized with the serialization strategy t +### Specifying serializer for a particular type + +[`@Serializable`][Serializable] annotation can also be applied directly to the types. +This is handy when a class that requires a custom serializer, such as `Date`, happens to be a generic type argument. +The most common use case for that is when you have a list of dates: + + + +```kotlin +@Serializable +class ProgrammingLanguage( + val name: String, + val releaseDates: List<@Serializable(DateAsLongSerializer::class) Date> +) + +fun main() { + val df = SimpleDateFormat("yyyy-MM-ddX") + val data = ProgrammingLanguage("Kotlin", listOf(df.parse("2023-07-06+00"), df.parse("2023-04-25+00"), df.parse("2022-12-28+00"))) + println(Json.encodeToString(data)) +} +``` + +> You can get the full code [here](../guide/example/example-serializer-16.kt). + +```text +{"name":"Kotlin","releaseDates":[1688601600000,1682380800000,1672185600000]} +``` + + + ### Specifying serializers for a file A serializer for a specific type, like `Date`, can be specified for a whole source code file with the file-level @@ -803,7 +843,7 @@ fun main() { println(Json.encodeToString(data)) } ``` -> You can get the full code [here](../guide/example/example-serializer-16.kt). +> You can get the full code [here](../guide/example/example-serializer-17.kt). ```text {"name":"Kotlin","stableReleaseDate":1455494400000} @@ -857,7 +897,7 @@ fun main() { } ``` -> You can get the full code [here](../guide/example/example-serializer-17.kt). +> You can get the full code [here](../guide/example/example-serializer-18.kt). ```text {"stableReleaseDate":"2016-02-15","lastReleaseTimestamp":1657152000000} @@ -905,7 +945,7 @@ fun main() { } ``` -> You can get the full code [here](../guide/example/example-serializer-18.kt). +> You can get the full code [here](../guide/example/example-serializer-19.kt). The resulting JSON looks like the `Project` class was serialized directly. @@ -969,7 +1009,7 @@ fun main() { To actually serialize this class we must provide the corresponding context when calling the `encodeToXxx`/`decodeFromXxx` functions. Without it we'll get a "Serializer for class 'Date' is not found" exception. -> See [here](../guide/example/example-serializer-19.kt) for an example that produces that exception. +> See [here](../guide/example/example-serializer-20.kt) for an example that produces that exception.