Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
sandwwraith committed Nov 13, 2023
2 parents cf71e08 + d5bc7f7 commit b2a05a4
Show file tree
Hide file tree
Showing 14 changed files with 188 additions and 106 deletions.
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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)
<details>
<summary>Using <code>apply plugin</code> (the old way)</summary>

First, you have to add the serialization plugin to your classpath as the other [compiler plugins](https://kotlinlang.org/docs/reference/compiler-plugins.html):

Expand Down Expand Up @@ -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'
```
</details>

#### 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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())
* ```
Expand Down
1 change: 1 addition & 0 deletions docs/serialization-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Once the project is set up, we can start serializing some classes.
* <a name='serializing-3rd-party-classes'></a>[Serializing 3rd party classes](serializers.md#serializing-3rd-party-classes)
* <a name='passing-a-serializer-manually'></a>[Passing a serializer manually](serializers.md#passing-a-serializer-manually)
* <a name='specifying-serializer-on-a-property'></a>[Specifying serializer on a property](serializers.md#specifying-serializer-on-a-property)
* <a name='specifying-serializer-for-a-particular-type'></a>[Specifying serializer for a particular type](serializers.md#specifying-serializer-for-a-particular-type)
* <a name='specifying-serializers-for-a-file'></a>[Specifying serializers for a file](serializers.md#specifying-serializers-for-a-file)
* <a name='specifying-serializer-globally-using-typealias'></a>[Specifying serializer globally using typealias](serializers.md#specifying-serializer-globally-using-typealias)
* <a name='custom-serializers-for-a-generic-type'></a>[Custom serializers for a generic type](serializers.md#custom-serializers-for-a-generic-type)
Expand Down
56 changes: 48 additions & 8 deletions docs/serializers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -770,6 +771,45 @@ The `stableReleaseDate` property is serialized with the serialization strategy t

<!--- TEST -->

### 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:

<!--- INCLUDE
import java.util.Date
import java.text.SimpleDateFormat

object DateAsLongSerializer : KSerializer<Date> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)
override fun serialize(encoder: Encoder, value: Date) = encoder.encodeLong(value.time)
override fun deserialize(decoder: Decoder): Date = Date(decoder.decodeLong())
}
-->

```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]}
```

<!--- TEST -->

### 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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.

<!--- TEST LINES_START
Exception in thread "main" kotlinx.serialization.SerializationException: Serializer for class 'Date' is not found.
Expand Down Expand Up @@ -1028,7 +1068,7 @@ fun main() {
}
```

> You can get the full code [here](../guide/example/example-serializer-20.kt).
> You can get the full code [here](../guide/example/example-serializer-21.kt).
```text
{"name":"Kotlin","stableReleaseDate":1455494400000}
```
Expand Down Expand Up @@ -1087,7 +1127,7 @@ fun main() {
}
```

> You can get the full code [here](../guide/example/example-serializer-21.kt).
> You can get the full code [here](../guide/example/example-serializer-22.kt).

This gets all the `Project` properties serialized:

Expand Down Expand Up @@ -1128,7 +1168,7 @@ fun main() {
}
```

> You can get the full code [here](../guide/example/example-serializer-22.kt).
> You can get the full code [here](../guide/example/example-serializer-23.kt).

The output is shown below.

Expand Down
5 changes: 3 additions & 2 deletions formats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ For convenience, they have same `groupId`, versioning and release cycle as core
|--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Avro | [sksamuel/avro4k](https://github.com/sksamuel/avro4k) <br> `com.sksamuel.avro4k:avro4k` | JVM only | This library allows serialization and deserialization of objects to and from [Avro](https://avro.apache.org). It will read and write from Avro binary or json streams or generate Avro Generic Records directly. It will also generate Avro schemas from data classes. The library allows for easy extension and overrides for custom schema formats, compatiblity with schemas defined outside out of the JVM and for types not supported out of the box. |
| Bson | [jershell/kbson](https://github.com/jershell/kbson) <br> `com.github.jershell:kbson` | JVM only | Allows serialization and deserialization of objects to and from [BSON](https://docs.mongodb.com/manual/reference/bson-types/). |
| TOML | [Peanuuutz/tomlkt](https://github.com/Peanuuutz/tomlkt) <br> `net.peanuuutz.tomlkt:tomlkt` | all supported platforms | Multiplatform encoder and decoder for [TOML](http://toml.io/) 1.0.0 compliant. This library aims to provide similar API to the official JSON format (such as TomlLiteral, TomlTable), while adding TOML specific features (such as @TomlComment, @TomlMultilineString). |
| TOML | [akuleshov7/ktoml](https://github.com/akuleshov7/ktoml) <br> `com.akuleshov7:ktoml-core` | all supported platforms | Fully Native and Multiplatform Kotlin serialization library for serialization/deserialization of TOML format. This library contains no Java code and no Java dependencies and it implements multiplatform parser, decoder and encoder of TOML. |
| Minecraft NBT | [BenWoodworth/knbt](https://github.com/BenWoodworth/knbt) <br> `net.benwoodworth.knbt:knbt` | all supported platforms | Implements the [NBT format](https://minecraft.fandom.com/wiki/NBT_format) for kotlinx.serialization, and provides a type-safe DSL for constructing NBT tags. |
| Minecraft NBT | [BenWoodworth/knbt](https://github.com/BenWoodworth/knbt) <br> `net.benwoodworth.knbt:knbt` | all supported platforms | Implements the [NBT format](https://minecraft.wiki/w/NBT_format) for kotlinx.serialization, and provides a type-safe DSL for constructing NBT tags. |
| MsgPack | [esensar/kotlinx-serialization-msgpack](https://github.com/esensar/kotlinx-serialization-msgpack) <br> `com.ensarsarajcic.kotlinx:serialization-msgpack` | all supported platforms | Allows serialization and deserialization of objects to and from [MsgPack](https://msgpack.org/). |
| SharedPreferences | [EdwarDDay/serialization.kprefs](https://github.com/EdwarDDay/serialization.kprefs) <br> `net.edwardday.serialization:kprefs` | Android only | This library allows serialization and deserialization of objects into and from Android [SharedPreferences](https://developer.android.com/reference/android/content/SharedPreferences). |
| XML | [pdvrieze/xmlutil](https://github.com/pdvrieze/xmlutil) <br> `io.github.pdvrieze.xmlutil:serialization` | all supported platforms | This library allows for reading and writing of XML documents with the serialization library. It is multiplatform, providing both a shared parser/writer for xml as well as platform-specific parsers where available. The library is designed to handle existing xml formats that use features that would not be available in other formats such as JSON. |
Expand All @@ -32,4 +33,4 @@ For convenience, they have same `groupId`, versioning and release cycle as core
| android.os.Bundle | [AhmedMourad0/bundlizer](https://github.com/AhmedMourad0/bundlizer) <br> `dev.ahmedmourad.bundlizer:bundlizer-core` | Android | Allow serialization and deserialization of objects to and from [android.os.Bundle](https://developer.android.com/reference/android/os/Bundle). |
| CSV | [hfhbd/kotlinx-serialization-csv](https://github.com/hfhbd/kotlinx-serialization-csv) <br> `app.softwork:kotlinx-serialization-csv` | all supported platforms | Allows serialization and deserialization of CSV files. There are still some limitations (ordered properties). |
| Fixed Length Format | [hfhbd/kotlinx-serialization-csv](https://github.com/hfhbd/kotlinx-serialization-csv) <br> `app.softwork:kotlinx-serialization-flf` | all supported platforms | Allows serialization and deserialization of [Fixed Length Format files](https://www.ibm.com/docs/en/psfa/7.2.1?topic=format-fixed-length-files). Each property must be annotated with `@FixedLength` and there are still some limitations due to missing delimiters. |
| JSON5 | [xn32/json5k](https://github.com/xn32/json5k) <br> `io.github.xn32:json5k` | JVM, Native | Library for the serialization to and deserialization from [JSON5](https://json5.org) text. |
| JSON5 | [xn32/json5k](https://github.com/xn32/json5k) <br> `io.github.xn32:json5k` | JVM, Native | Library for the serialization to and deserialization from [JSON5](https://json5.org) text. |
9 changes: 6 additions & 3 deletions guide/example/example-serializer-16.kt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@file:UseSerializers(DateAsLongSerializer::class)
// This file was automatically generated from serializers.md by Knit tool. Do not edit.
package example.exampleSerializer16

Expand All @@ -17,9 +16,13 @@ object DateAsLongSerializer : KSerializer<Date> {
}

@Serializable
class ProgrammingLanguage(val name: String, val stableReleaseDate: Date)
class ProgrammingLanguage(
val name: String,
val releaseDates: List<@Serializable(DateAsLongSerializer::class) Date>
)

fun main() {
val data = ProgrammingLanguage("Kotlin", SimpleDateFormat("yyyy-MM-ddX").parse("2016-02-15+00"))
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))
}
Loading

0 comments on commit b2a05a4

Please sign in to comment.