<commit_before># Json-specific serializers

To affect the shape and contents of JSON output after serialization, or adapt input to deserialization,
it is possible to write a [custom serializer](custom_serializers.md). However, it may not be convenient to
carefully follow complex Encoder and Decoder calling conventions, especially for relatively small and easy tasks.
For that purpose, `kotlinx.serialization` library gives you API that
can boil down the burden of implementing a custom serializer to a problem of manipulating a Json elements tree.

* [Prerequisites](#prerequisites)
* [Json transformations](#json-transformations)
    + [Samples](#samples)
* [Json parametric polymorphic deserialization](#json-parametric-polymorphic-deserialization)
* [Under the hood](#under-the-hood)

## Prerequisites

It is still strongly recommended to be acquainted with [custom serializers guide](custom_serializers.md)
in its [using serializers](custom_serializers.md#using-custom-serializers) part,
since the instantiation process and annotations to enable custom serializers remain the same.
It is also important to remember that since the discussed in this article serializers are manipulating Json tree,
they work only with Json format.

## Json transformations

Transformation capabilities are provided by the abstract `JsonTransformingSerializer` class that implements `KSerializer`. 

Instead of direct interaction with Encoder or Decoder, this class asks you to supply transformations for JSON tree represented by the `JsonElement` class
using `writeTransform(element: JsonElement): JsonElement` and `readTransform(element: JsonElement): JsonElement` methods in order
to transform the input or the putput JSON.


### Transformation examples. List mainupulation

The first example is our own implementation of list wrapping. Consider the API that returns list 
of objects, or, if there is only one element in the result, then it is a single object, not wrapped in the list.
 
To simplify object model, it is possible to implement transforming serializer that always returns list of objects,
automatically wrapping a single object in a list as well: 

```kotlin
@Serializable // Sample class with data
data class StringData(val data: String)

<commit_msg>Fix typo (#821)<commit_after># Json-specific serializers

To affect the shape and contents of JSON output after serialization, or adapt input to deserialization,
it is possible to write a [custom serializer](custom_serializers.md). However, it may not be convenient to
carefully follow complex Encoder and Decoder calling conventions, especially for relatively small and easy tasks.
For that purpose, `kotlinx.serialization` library gives you API that
can boil down the burden of implementing a custom serializer to a problem of manipulating a Json elements tree.

* [Prerequisites](#prerequisites)
* [Json transformations](#json-transformations)
    + [Samples](#samples)
* [Json parametric polymorphic deserialization](#json-parametric-polymorphic-deserialization)
* [Under the hood](#under-the-hood)

## Prerequisites

It is still strongly recommended to be acquainted with [custom serializers guide](custom_serializers.md)
in its [using serializers](custom_serializers.md#using-custom-serializers) part,
since the instantiation process and annotations to enable custom serializers remain the same.
It is also important to remember that since the discussed in this article serializers are manipulating Json tree,
they work only with Json format.

## Json transformations

Transformation capabilities are provided by the abstract `JsonTransformingSerializer` class that implements `KSerializer`. 

Instead of direct interaction with Encoder or Decoder, this class asks you to supply transformations for JSON tree represented by the `JsonElement` class
using `writeTransform(element: JsonElement): JsonElement` and `readTransform(element: JsonElement): JsonElement` methods in order
to transform the input or the output JSON.


### Transformation examples. List mainupulation

The first example is our own implementation of list wrapping. Consider the API that returns list 
of objects, or, if there is only one element in the result, then it is a single object, not wrapped in the list.
 
To simplify object model, it is possible to implement transforming serializer that always returns list of objects,
automatically wrapping a single object in a list as well: 

```kotlin
@Serializable // Sample class with data
data class StringData(val data: String)


{'fraction_non_alphanumeric': 0.05429964539007092, 'fraction_numerical': 0.0006648936170212766, 'mean_word_length': 5.705794947994057, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '637761', 'n_tokens_mistral': 1106, 'n_tokens_neox': 1029, 'n_words': 562}